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;
}







19















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
    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





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

    – Max Langhof
    19 hours ago




















19















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
    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





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

    – Max Langhof
    19 hours ago
















19












19








19


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 19 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 19 hours ago









Luca ParisiLuca Parisi

984




984




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
    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





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

    – Max Langhof
    19 hours ago
















  • 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 about std::vector but just about non-trivial destructors.

    – Max Langhof
    19 hours ago








  • 1





    Solution is simple: Make dimensions a static function (and remove the const). 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














1 Answer
1






active

oldest

votes


















19














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









    19














    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




























      19














      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


























        19












        19








        19







        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 19 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







            Popular posts from this blog

            Why do type traits not work with types in namespace scope?What are POD types in C++?Why can templates only be...

            Will tsunami waves travel forever if there was no land?Why do tsunami waves begin with the water flowing away...

            Should I use Docker or LXD?How to cache (more) data on SSD/RAM to avoid spin up?Unable to get Windows File...