constexpr member function with std::vector data member in C++Storing C++ template function definitions in a...
How to pronounce 'c++' in Spanish
Can I criticise the more senior developers around me for not writing clean code?
Re-entry to Germany after vacation using blue card
How did Captain America manage to do this?
Why did C use the -> operator instead of reusing the . operator?
How does Captain America channel this power?
A strange hotel
Does a large simulator bay have standard public address announcements?
Why was the Spitfire's elliptical wing almost uncopied by other aircraft of World War 2?
What's the name of these pliers?
Was Dennis Ritchie being too modest in this quote about C and Pascal?
Why must Chinese maps be obfuscated?
Two field separators (colon and space) in awk
Apply MapThread to all but one variable
Critique of timeline aesthetic
Does tea made with boiling water cool faster than tea made with boiled (but still hot) water?
Pre-plastic human skin alternative
Extension of 2-adic valuation to the real numbers
Can an Area of Effect spell cast outside a Prismatic Wall extend inside it?
How can I practically buy stocks?
Is Diceware more secure than a long passphrase?
What is causing the white spot to appear in some of my pictures
Is there really no use for MD5 anymore?
Is this homebrew Wind Wave spell balanced?
constexpr member function with std::vector data member in C++
Storing C++ template function definitions in a .CPP fileWhy do we need virtual functions in C++?g++ doesn't compile constexpr function with assert in itSFINAE constexpr with std::getWhy cannot std::stol be converted to a std::function object?Constexpr member function in class templateNon-const constexpr member function does not compile with Intel compilermember function that is not const should only be constexpr if on C++14 or laterWarning: ISO C++ forbids converting a string constant to ‘char*’ for a static `constexpr char*` data memberConstexpr static member function usage
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I am trying to implement in a C++ class a constexpr member function which returns a template parameter. The code is supposed to be c++11 compatible. However I encounter compilation issues when the templated class also contains STL containers as data members such as std::vector (which are untouched by the constexpr member function).
A minimal example is given by the following code:
#include <vector>
#include <iostream>
#include <array>
template<size_t n>
struct A
{
constexpr size_t dimensions() const
{
return n;
}
private:
std::vector<double> a;
};
int main(int argc,char ** argv)
{
auto a=A<3>();
std::array<double,a.dimensions()> arr;
}
The code compiles correctly with the commands
g++ -std=c++14 -O3 quickTest.cpp -o test -Wall
clang++ -std=c++11 -O3 quickTest.cpp -o test -Wall
but fails when I use
g++ -std=c++11 -O3 quickTest.cpp -o test -Wall
with the error
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:10:20: note: ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’ is not usable as a ‘constexpr’ function because:
constexpr size_t dimensions() const
^~~~~~~~~~
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:22:33: note: in template argument for type ‘long unsigned int’
Why does the code not compile with gcc -std=c++11
but does compile with clang++ -std=c++11
?
How could one make this code snippet work with older versions of gcc which many not support c++14/17, but only c++11 ?
I am using gcc 8.1.1 and clang 6.0.1
c++ c++11 constexpr
New contributor
add a comment |
I am trying to implement in a C++ class a constexpr member function which returns a template parameter. The code is supposed to be c++11 compatible. However I encounter compilation issues when the templated class also contains STL containers as data members such as std::vector (which are untouched by the constexpr member function).
A minimal example is given by the following code:
#include <vector>
#include <iostream>
#include <array>
template<size_t n>
struct A
{
constexpr size_t dimensions() const
{
return n;
}
private:
std::vector<double> a;
};
int main(int argc,char ** argv)
{
auto a=A<3>();
std::array<double,a.dimensions()> arr;
}
The code compiles correctly with the commands
g++ -std=c++14 -O3 quickTest.cpp -o test -Wall
clang++ -std=c++11 -O3 quickTest.cpp -o test -Wall
but fails when I use
g++ -std=c++11 -O3 quickTest.cpp -o test -Wall
with the error
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:10:20: note: ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’ is not usable as a ‘constexpr’ function because:
constexpr size_t dimensions() const
^~~~~~~~~~
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:22:33: note: in template argument for type ‘long unsigned int’
Why does the code not compile with gcc -std=c++11
but does compile with clang++ -std=c++11
?
How could one make this code snippet work with older versions of gcc which many not support c++14/17, but only c++11 ?
I am using gcc 8.1.1 and clang 6.0.1
c++ c++11 constexpr
New contributor
1
C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.
– Marek R
19 hours ago
If you enable more warnings, the compiler tells you the issue: godbolt.org/z/hRMsN0warning: enclosing class of 'constexpr' non-static member function 'size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]' is not a literal type [-Wpedantic]
,note: 'A<3>' is not literal because: 'A<3>' has a non-trivial destructor
-> It's not aboutstd::vector
but just about non-trivial destructors.
– Max Langhof
19 hours ago
1
Solution is simple: Makedimensions
astatic
function (and remove theconst
). godbolt.org/z/y_YuMU
– Max Langhof
19 hours ago
add a comment |
I am trying to implement in a C++ class a constexpr member function which returns a template parameter. The code is supposed to be c++11 compatible. However I encounter compilation issues when the templated class also contains STL containers as data members such as std::vector (which are untouched by the constexpr member function).
A minimal example is given by the following code:
#include <vector>
#include <iostream>
#include <array>
template<size_t n>
struct A
{
constexpr size_t dimensions() const
{
return n;
}
private:
std::vector<double> a;
};
int main(int argc,char ** argv)
{
auto a=A<3>();
std::array<double,a.dimensions()> arr;
}
The code compiles correctly with the commands
g++ -std=c++14 -O3 quickTest.cpp -o test -Wall
clang++ -std=c++11 -O3 quickTest.cpp -o test -Wall
but fails when I use
g++ -std=c++11 -O3 quickTest.cpp -o test -Wall
with the error
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:10:20: note: ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’ is not usable as a ‘constexpr’ function because:
constexpr size_t dimensions() const
^~~~~~~~~~
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:22:33: note: in template argument for type ‘long unsigned int’
Why does the code not compile with gcc -std=c++11
but does compile with clang++ -std=c++11
?
How could one make this code snippet work with older versions of gcc which many not support c++14/17, but only c++11 ?
I am using gcc 8.1.1 and clang 6.0.1
c++ c++11 constexpr
New contributor
I am trying to implement in a C++ class a constexpr member function which returns a template parameter. The code is supposed to be c++11 compatible. However I encounter compilation issues when the templated class also contains STL containers as data members such as std::vector (which are untouched by the constexpr member function).
A minimal example is given by the following code:
#include <vector>
#include <iostream>
#include <array>
template<size_t n>
struct A
{
constexpr size_t dimensions() const
{
return n;
}
private:
std::vector<double> a;
};
int main(int argc,char ** argv)
{
auto a=A<3>();
std::array<double,a.dimensions()> arr;
}
The code compiles correctly with the commands
g++ -std=c++14 -O3 quickTest.cpp -o test -Wall
clang++ -std=c++11 -O3 quickTest.cpp -o test -Wall
but fails when I use
g++ -std=c++11 -O3 quickTest.cpp -o test -Wall
with the error
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:10:20: note: ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’ is not usable as a ‘constexpr’ function because:
constexpr size_t dimensions() const
^~~~~~~~~~
quickTest.cpp:22:33: error: call to non-‘constexpr’ function ‘size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]’
std::array<double,a.dimensions()> arr;
~~~~~~~~~~~~^~
quickTest.cpp:22:33: note: in template argument for type ‘long unsigned int’
Why does the code not compile with gcc -std=c++11
but does compile with clang++ -std=c++11
?
How could one make this code snippet work with older versions of gcc which many not support c++14/17, but only c++11 ?
I am using gcc 8.1.1 and clang 6.0.1
c++ c++11 constexpr
c++ c++11 constexpr
New contributor
New contributor
edited 19 hours ago
Luca Parisi
New contributor
asked 19 hours ago
Luca ParisiLuca Parisi
984
984
New contributor
New contributor
1
C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.
– Marek R
19 hours ago
If you enable more warnings, the compiler tells you the issue: godbolt.org/z/hRMsN0warning: enclosing class of 'constexpr' non-static member function 'size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]' is not a literal type [-Wpedantic]
,note: 'A<3>' is not literal because: 'A<3>' has a non-trivial destructor
-> It's not aboutstd::vector
but just about non-trivial destructors.
– Max Langhof
19 hours ago
1
Solution is simple: Makedimensions
astatic
function (and remove theconst
). godbolt.org/z/y_YuMU
– Max Langhof
19 hours ago
add a comment |
1
C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.
– Marek R
19 hours ago
If you enable more warnings, the compiler tells you the issue: godbolt.org/z/hRMsN0warning: enclosing class of 'constexpr' non-static member function 'size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]' is not a literal type [-Wpedantic]
,note: 'A<3>' is not literal because: 'A<3>' has a non-trivial destructor
-> It's not aboutstd::vector
but just about non-trivial destructors.
– Max Langhof
19 hours ago
1
Solution is simple: Makedimensions
astatic
function (and remove theconst
). godbolt.org/z/y_YuMU
– Max Langhof
19 hours ago
1
1
C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.
– Marek R
19 hours ago
C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.
– Marek R
19 hours ago
If you enable more warnings, the compiler tells you the issue: godbolt.org/z/hRMsN0
warning: enclosing class of 'constexpr' non-static member function 'size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]' is not a literal type [-Wpedantic]
, note: 'A<3>' is not literal because: 'A<3>' has a non-trivial destructor
-> It's not about std::vector
but just about non-trivial destructors.– Max Langhof
19 hours ago
If you enable more warnings, the compiler tells you the issue: godbolt.org/z/hRMsN0
warning: enclosing class of 'constexpr' non-static member function 'size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]' is not a literal type [-Wpedantic]
, note: 'A<3>' is not literal because: 'A<3>' has a non-trivial destructor
-> It's not about std::vector
but just about non-trivial destructors.– Max Langhof
19 hours ago
1
1
Solution is simple: Make
dimensions
a static
function (and remove the const
). godbolt.org/z/y_YuMU– Max Langhof
19 hours ago
Solution is simple: Make
dimensions
a static
function (and remove the const
). godbolt.org/z/y_YuMU– Max Langhof
19 hours ago
add a comment |
1 Answer
1
active
oldest
votes
C++11 had a rule [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
is not a literal type because of the vector
, hence its non-static member functions cannot be constexpr
.
So GCC is right to reject the code in C++11 mode.
C++14 removed that restriction.
The solution for C++11 is to declare dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}
Live demo
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Luca Parisi is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55866212%2fconstexpr-member-function-with-stdvector-data-member-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
C++11 had a rule [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
is not a literal type because of the vector
, hence its non-static member functions cannot be constexpr
.
So GCC is right to reject the code in C++11 mode.
C++14 removed that restriction.
The solution for C++11 is to declare dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}
Live demo
add a comment |
C++11 had a rule [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
is not a literal type because of the vector
, hence its non-static member functions cannot be constexpr
.
So GCC is right to reject the code in C++11 mode.
C++14 removed that restriction.
The solution for C++11 is to declare dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}
Live demo
add a comment |
C++11 had a rule [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
is not a literal type because of the vector
, hence its non-static member functions cannot be constexpr
.
So GCC is right to reject the code in C++11 mode.
C++14 removed that restriction.
The solution for C++11 is to declare dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}
Live demo
C++11 had a rule [dcl.constexpr]/8:
... The class of which that function is a member shall be a literal type ([basic.types]).
struct A
is not a literal type because of the vector
, hence its non-static member functions cannot be constexpr
.
So GCC is right to reject the code in C++11 mode.
C++14 removed that restriction.
The solution for C++11 is to declare dimensions()
static
:
static constexpr size_t dimensions()
{
return n;
}
Live demo
answered 19 hours ago
rustyxrustyx
34k9104145
34k9104145
add a comment |
add a comment |
Luca Parisi is a new contributor. Be nice, and check out our Code of Conduct.
Luca Parisi is a new contributor. Be nice, and check out our Code of Conduct.
Luca Parisi is a new contributor. Be nice, and check out our Code of Conduct.
Luca Parisi is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55866212%2fconstexpr-member-function-with-stdvector-data-member-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.
– Marek R
19 hours ago
If you enable more warnings, the compiler tells you the issue: godbolt.org/z/hRMsN0
warning: enclosing class of 'constexpr' non-static member function 'size_t A<n>::dimensions() const [with long unsigned int n = 3; size_t = long unsigned int]' is not a literal type [-Wpedantic]
,note: 'A<3>' is not literal because: 'A<3>' has a non-trivial destructor
-> It's not aboutstd::vector
but just about non-trivial destructors.– Max Langhof
19 hours ago
1
Solution is simple: Make
dimensions
astatic
function (and remove theconst
). godbolt.org/z/y_YuMU– Max Langhof
19 hours ago