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

Pulling the rope with one hand is as heavy as with two hands?

How to limit Drive Letters Windows assigns to new removable USB drives

"Whatever a Russian does, they end up making the Kalashnikov gun"? Are there any similar proverbs in English?

Like totally amazing interchangeable sister outfits II: The Revenge

Check if a string is entirely made of the same substring

How could Tony Stark make this in Endgame?

Is there really no use for MD5 anymore?

Why didn't the Space Shuttle bounce back into space as many times as possible so as to lose a lot of kinetic energy up there?

How to not starve gigantic beasts

What is the smallest unit of eos?

Can an Area of Effect spell cast outside a Prismatic Wall extend inside it?

Pre-plastic human skin alternative

Don’t seats that recline flat defeat the purpose of having seatbelts?

As an international instructor, should I openly talk about my accent?

Why does nature favour the Laplacian?

How to denote matrix elements succinctly?

Rivers without rain

Do I have an "anti-research" personality?

Who was the lone kid in the line of people at the lake at the end of Avengers: Endgame?

What does the integral of a function times a function of a random variable represent, conceptually?

How much cash can I safely carry into the USA and avoid civil forfeiture?

Are there physical dangers to preparing a prepared piano?

Did the BCPL programming language support floats?

Which big number is bigger?



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;








18















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










share|improve this question









New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1





    C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.

    – Marek R
    10 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
    10 hours ago







  • 1





    Solution is simple: Make dimensions a static function (and remove the const). godbolt.org/z/y_YuMU

    – Max Langhof
    10 hours ago


















18















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










share|improve this question









New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.















  • 1





    C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.

    – Marek R
    10 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
    10 hours ago







  • 1





    Solution is simple: Make dimensions a static function (and remove the const). godbolt.org/z/y_YuMU

    – Max Langhof
    10 hours ago














18












18








18


1






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










share|improve this question









New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












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






share|improve this question









New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 10 hours ago







Luca Parisi













New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 10 hours ago









Luca ParisiLuca Parisi

934




934




New contributor




Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Luca Parisi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







  • 1





    C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.

    – Marek R
    10 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
    10 hours ago







  • 1





    Solution is simple: Make dimensions a static function (and remove the const). godbolt.org/z/y_YuMU

    – Max Langhof
    10 hours ago













  • 1





    C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.

    – Marek R
    10 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
    10 hours ago







  • 1





    Solution is simple: Make dimensions a static function (and remove the const). godbolt.org/z/y_YuMU

    – Max Langhof
    10 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
10 hours ago






C++14 Relaxed constexpr restrictions so this is fine. Question is who is right gcc or clang? IMO gcc.

– Marek R
10 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
10 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
10 hours ago





1




1





Solution is simple: Make dimensions a static function (and remove the const). godbolt.org/z/y_YuMU

– Max Langhof
10 hours ago






Solution is simple: Make dimensions a static function (and remove the const). godbolt.org/z/y_YuMU

– Max Langhof
10 hours ago













1 Answer
1






active

oldest

votes


















18














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






share|improve this answer























    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.









    draft saved

    draft discarded


















    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









    18














    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






    share|improve this answer



























      18














      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






      share|improve this answer

























        18












        18








        18







        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






        share|improve this answer













        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







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 10 hours ago









        rustyxrustyx

        34k9104145




        34k9104145






















            Luca Parisi is a new contributor. Be nice, and check out our Code of Conduct.









            draft saved

            draft discarded


















            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.




            draft saved


            draft discarded














            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





















































            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