Linkage issues when using a static constexpr as default constructor argumentUndefined reference to static constexpr string (except if it's a pointer)What's the point of g++ -Wreorder?When should you use constexpr capability in C++11?How do I pass a unique_ptr argument to a constructor or a function?C++11 make_pair with specified template parameters doesn't compileCompile errors using std::bind in gcc 4.7std::atomic_is_lock_free(shared_ptr<T>*) didn't compileWhy is it not possible to instantiate pair with “non const” copy constructor while it is possible to instantiate one without?Is it possible to initialize constexpr std::array member in a programtic wayPassing variadic template to pthread_createWhy did this error occur? c++ library build

Team goes to lunch frequently, I do intermittent fasting but still want to socialize

Should you play baroque pieces a semitone lower?

Three legged NOT gate? What is this symbol?

How to mark beverage cans in a cooler for a blind person?

Why do funding agencies like the NSF not publish accepted grants?

Why isn’t SHA-3 in wider use?

Acceptable to cut steak before searing?

Are differences between uniformly distributed numbers uniformly distributed?

Identification of vintage sloping window

Ex-contractor published company source code and secrets online

Multirow in tabularx?

Who are these characters/superheroes in the posters from Chris's room in Family Guy?

What happen to those who died but not from the snap?

Why do oscilloscopes use SMPSes instead of linear power supplies?

Opposite for desideratum to mean "something not wished for"

Why did the RAAF procure the F/A-18 despite being purpose-built for carriers?

How does 'AND' distribute over 'OR' (Set Theory)?

Resonance and mesomeric effect

How many different ways are there to checkmate in the early game?

Is TA-ing worth the opportunity cost?

I accidentally overwrote a Linux binary file

Was the 2019 Lion King film made through motion capture?

What are the uses and limitations of Persuasion, Insight, and Deception against other PCs?

The equation of motion for a scalar field in curved spacetime in terms of the covariant derivative



Linkage issues when using a static constexpr as default constructor argument


Undefined reference to static constexpr string (except if it's a pointer)What's the point of g++ -Wreorder?When should you use constexpr capability in C++11?How do I pass a unique_ptr argument to a constructor or a function?C++11 make_pair with specified template parameters doesn't compileCompile errors using std::bind in gcc 4.7std::atomic_is_lock_free(shared_ptr<T>*) didn't compileWhy is it not possible to instantiate pair with “non const” copy constructor while it is possible to instantiate one without?Is it possible to initialize constexpr std::array member in a programtic wayPassing variadic template to pthread_createWhy did this error occur? c++ library build






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








-1















I would like somebody to clarify in which cases it is safe to use a static constexpr as a default argument to a class's constructor. To weed out exactly what is going on, consider the following code:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



This code seems to compile, but does not link. Specifically, when compiling with GCC 6.3, I get



prog.cc:(.text+0x13): undefined reference to `Bar::default_options'
collect2: error: ld returned 1 exit status


However, if we comment out the offending line, then the code compiles, links, and runs correctly. So presumably there is no problem using a static constexpr size_t as a default argument:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
//Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



Can somebody explain to me why the linkage works for a size_t, but not for an array of them?



I am aware that I could define the default options inline like this:



Bar(
Options options = std::array<Option, 0>,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;



I was just wondering if there was any other nicer fix so that the default options could easily be queried by anyone.










share|improve this question


























  • Are you building as C++14?

    – StoryTeller
    Mar 27 at 8:45






  • 1





    It won't. C++17 would. Just asked to add the appropriate tags.

    – StoryTeller
    Mar 27 at 8:47







  • 1





    GCC 6.3 doesn't support C++17 fully. In GCC 7.1 it works as intended wandbox.org/permlink/7T2gdl4uoayhJn1Z

    – StoryTeller
    Mar 27 at 8:49







  • 1





    As an aside, how did you get a permalink to Wandbox? I also was making the example there, but I never was able to figure out how to generate a permalink

    – bremen_matt
    Mar 27 at 8:54






  • 2





    After you hist "run" there appears a "share" option above the output panel. Hitting that gives you a "URL" anchor with the permalink and a twitter "share" option :)

    – StoryTeller
    Mar 27 at 8:55

















-1















I would like somebody to clarify in which cases it is safe to use a static constexpr as a default argument to a class's constructor. To weed out exactly what is going on, consider the following code:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



This code seems to compile, but does not link. Specifically, when compiling with GCC 6.3, I get



prog.cc:(.text+0x13): undefined reference to `Bar::default_options'
collect2: error: ld returned 1 exit status


However, if we comment out the offending line, then the code compiles, links, and runs correctly. So presumably there is no problem using a static constexpr size_t as a default argument:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
//Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



Can somebody explain to me why the linkage works for a size_t, but not for an array of them?



I am aware that I could define the default options inline like this:



Bar(
Options options = std::array<Option, 0>,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;



I was just wondering if there was any other nicer fix so that the default options could easily be queried by anyone.










share|improve this question


























  • Are you building as C++14?

    – StoryTeller
    Mar 27 at 8:45






  • 1





    It won't. C++17 would. Just asked to add the appropriate tags.

    – StoryTeller
    Mar 27 at 8:47







  • 1





    GCC 6.3 doesn't support C++17 fully. In GCC 7.1 it works as intended wandbox.org/permlink/7T2gdl4uoayhJn1Z

    – StoryTeller
    Mar 27 at 8:49







  • 1





    As an aside, how did you get a permalink to Wandbox? I also was making the example there, but I never was able to figure out how to generate a permalink

    – bremen_matt
    Mar 27 at 8:54






  • 2





    After you hist "run" there appears a "share" option above the output panel. Hitting that gives you a "URL" anchor with the permalink and a twitter "share" option :)

    – StoryTeller
    Mar 27 at 8:55













-1












-1








-1








I would like somebody to clarify in which cases it is safe to use a static constexpr as a default argument to a class's constructor. To weed out exactly what is going on, consider the following code:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



This code seems to compile, but does not link. Specifically, when compiling with GCC 6.3, I get



prog.cc:(.text+0x13): undefined reference to `Bar::default_options'
collect2: error: ld returned 1 exit status


However, if we comment out the offending line, then the code compiles, links, and runs correctly. So presumably there is no problem using a static constexpr size_t as a default argument:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
//Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



Can somebody explain to me why the linkage works for a size_t, but not for an array of them?



I am aware that I could define the default options inline like this:



Bar(
Options options = std::array<Option, 0>,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;



I was just wondering if there was any other nicer fix so that the default options could easily be queried by anyone.










share|improve this question
















I would like somebody to clarify in which cases it is safe to use a static constexpr as a default argument to a class's constructor. To weed out exactly what is going on, consider the following code:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



This code seems to compile, but does not link. Specifically, when compiling with GCC 6.3, I get



prog.cc:(.text+0x13): undefined reference to `Bar::default_options'
collect2: error: ld returned 1 exit status


However, if we comment out the offending line, then the code compiles, links, and runs correctly. So presumably there is no problem using a static constexpr size_t as a default argument:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
//Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;

;

int main()
Bar bar;



Can somebody explain to me why the linkage works for a size_t, but not for an array of them?



I am aware that I could define the default options inline like this:



Bar(
Options options = std::array<Option, 0>,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;



I was just wondering if there was any other nicer fix so that the default options could easily be queried by anyone.







c++ c++11






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 27 at 8:48







bremen_matt

















asked Mar 27 at 8:37









bremen_mattbremen_matt

3,0932 gold badges22 silver badges45 bronze badges




3,0932 gold badges22 silver badges45 bronze badges















  • Are you building as C++14?

    – StoryTeller
    Mar 27 at 8:45






  • 1





    It won't. C++17 would. Just asked to add the appropriate tags.

    – StoryTeller
    Mar 27 at 8:47







  • 1





    GCC 6.3 doesn't support C++17 fully. In GCC 7.1 it works as intended wandbox.org/permlink/7T2gdl4uoayhJn1Z

    – StoryTeller
    Mar 27 at 8:49







  • 1





    As an aside, how did you get a permalink to Wandbox? I also was making the example there, but I never was able to figure out how to generate a permalink

    – bremen_matt
    Mar 27 at 8:54






  • 2





    After you hist "run" there appears a "share" option above the output panel. Hitting that gives you a "URL" anchor with the permalink and a twitter "share" option :)

    – StoryTeller
    Mar 27 at 8:55

















  • Are you building as C++14?

    – StoryTeller
    Mar 27 at 8:45






  • 1





    It won't. C++17 would. Just asked to add the appropriate tags.

    – StoryTeller
    Mar 27 at 8:47







  • 1





    GCC 6.3 doesn't support C++17 fully. In GCC 7.1 it works as intended wandbox.org/permlink/7T2gdl4uoayhJn1Z

    – StoryTeller
    Mar 27 at 8:49







  • 1





    As an aside, how did you get a permalink to Wandbox? I also was making the example there, but I never was able to figure out how to generate a permalink

    – bremen_matt
    Mar 27 at 8:54






  • 2





    After you hist "run" there appears a "share" option above the output panel. Hitting that gives you a "URL" anchor with the permalink and a twitter "share" option :)

    – StoryTeller
    Mar 27 at 8:55
















Are you building as C++14?

– StoryTeller
Mar 27 at 8:45





Are you building as C++14?

– StoryTeller
Mar 27 at 8:45




1




1





It won't. C++17 would. Just asked to add the appropriate tags.

– StoryTeller
Mar 27 at 8:47






It won't. C++17 would. Just asked to add the appropriate tags.

– StoryTeller
Mar 27 at 8:47





1




1





GCC 6.3 doesn't support C++17 fully. In GCC 7.1 it works as intended wandbox.org/permlink/7T2gdl4uoayhJn1Z

– StoryTeller
Mar 27 at 8:49






GCC 6.3 doesn't support C++17 fully. In GCC 7.1 it works as intended wandbox.org/permlink/7T2gdl4uoayhJn1Z

– StoryTeller
Mar 27 at 8:49





1




1





As an aside, how did you get a permalink to Wandbox? I also was making the example there, but I never was able to figure out how to generate a permalink

– bremen_matt
Mar 27 at 8:54





As an aside, how did you get a permalink to Wandbox? I also was making the example there, but I never was able to figure out how to generate a permalink

– bremen_matt
Mar 27 at 8:54




2




2





After you hist "run" there appears a "share" option above the output panel. Hitting that gives you a "URL" anchor with the permalink and a twitter "share" option :)

– StoryTeller
Mar 27 at 8:55





After you hist "run" there appears a "share" option above the output panel. Hitting that gives you a "URL" anchor with the permalink and a twitter "share" option :)

– StoryTeller
Mar 27 at 8:55












1 Answer
1






active

oldest

votes


















2














As StoryTeller points out, the first code DOES compile and link with C++17 and GCC 7.1+. To get this to compile with C++11 and older versions of GCC, you need an out-of-class declaration of the array:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;
std::cout << "Constructed with options..." << std::endl;
for (auto & other_option : options)
std::cout << other_option << ", ";
std::cout << std::endl;

;

// !!!! Needed for C++11 and lower gcc<7.1 versions
constexpr Bar::Options Bar::default_options;

int main()
Bar bar;






share|improve this answer




















  • 1





    Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

    – Daniel H
    Mar 27 at 9:17











  • I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

    – bremen_matt
    Mar 27 at 9:33












  • Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

    – bremen_matt
    Mar 27 at 9:35











  • I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

    – Daniel H
    Mar 28 at 2:05










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



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55372841%2flinkage-issues-when-using-a-static-constexpr-as-default-constructor-argument%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









2














As StoryTeller points out, the first code DOES compile and link with C++17 and GCC 7.1+. To get this to compile with C++11 and older versions of GCC, you need an out-of-class declaration of the array:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;
std::cout << "Constructed with options..." << std::endl;
for (auto & other_option : options)
std::cout << other_option << ", ";
std::cout << std::endl;

;

// !!!! Needed for C++11 and lower gcc<7.1 versions
constexpr Bar::Options Bar::default_options;

int main()
Bar bar;






share|improve this answer




















  • 1





    Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

    – Daniel H
    Mar 27 at 9:17











  • I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

    – bremen_matt
    Mar 27 at 9:33












  • Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

    – bremen_matt
    Mar 27 at 9:35











  • I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

    – Daniel H
    Mar 28 at 2:05















2














As StoryTeller points out, the first code DOES compile and link with C++17 and GCC 7.1+. To get this to compile with C++11 and older versions of GCC, you need an out-of-class declaration of the array:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;
std::cout << "Constructed with options..." << std::endl;
for (auto & other_option : options)
std::cout << other_option << ", ";
std::cout << std::endl;

;

// !!!! Needed for C++11 and lower gcc<7.1 versions
constexpr Bar::Options Bar::default_options;

int main()
Bar bar;






share|improve this answer




















  • 1





    Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

    – Daniel H
    Mar 27 at 9:17











  • I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

    – bremen_matt
    Mar 27 at 9:33












  • Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

    – bremen_matt
    Mar 27 at 9:35











  • I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

    – Daniel H
    Mar 28 at 2:05













2












2








2







As StoryTeller points out, the first code DOES compile and link with C++17 and GCC 7.1+. To get this to compile with C++11 and older versions of GCC, you need an out-of-class declaration of the array:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;
std::cout << "Constructed with options..." << std::endl;
for (auto & other_option : options)
std::cout << other_option << ", ";
std::cout << std::endl;

;

// !!!! Needed for C++11 and lower gcc<7.1 versions
constexpr Bar::Options Bar::default_options;

int main()
Bar bar;






share|improve this answer













As StoryTeller points out, the first code DOES compile and link with C++17 and GCC 7.1+. To get this to compile with C++11 and older versions of GCC, you need an out-of-class declaration of the array:



#include <array>
#include <iostream>

struct Bar

using Option = size_t;
using Options = std::array<Option, 0>;
static constexpr Option default_option = 8080;
static constexpr Options default_options;

//template <typename OptionT = Options>
Bar(
Options options = default_options,
Option option = default_option
)
std::cout << "Constructed with option " << option << std::endl;
std::cout << "Constructed with options..." << std::endl;
for (auto & other_option : options)
std::cout << other_option << ", ";
std::cout << std::endl;

;

// !!!! Needed for C++11 and lower gcc<7.1 versions
constexpr Bar::Options Bar::default_options;

int main()
Bar bar;







share|improve this answer












share|improve this answer



share|improve this answer










answered Mar 27 at 9:10









bremen_mattbremen_matt

3,0932 gold badges22 silver badges45 bronze badges




3,0932 gold badges22 silver badges45 bronze badges










  • 1





    Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

    – Daniel H
    Mar 27 at 9:17











  • I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

    – bremen_matt
    Mar 27 at 9:33












  • Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

    – bremen_matt
    Mar 27 at 9:35











  • I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

    – Daniel H
    Mar 28 at 2:05












  • 1





    Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

    – Daniel H
    Mar 27 at 9:17











  • I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

    – bremen_matt
    Mar 27 at 9:33












  • Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

    – bremen_matt
    Mar 27 at 9:35











  • I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

    – Daniel H
    Mar 28 at 2:05







1




1





Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

– Daniel H
Mar 27 at 9:17





Pre C++17 the line constexpr Bar::Options Bar::default_options; is actually the definition, not the declaration. It says to the compiler "I said that Bar had a member default_options; it belongs here". This isn't just pedantry; it means that the line cannot go in a header file that's included in multiple locations.

– Daniel H
Mar 27 at 9:17













I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

– bremen_matt
Mar 27 at 9:33






I am a little confused by that statement because in C++11, if I don't have the in-class initialization: default_options;, that is, if I remove the trailing braces, then I get the error 'default_options' must have an initializer.

– bremen_matt
Mar 27 at 9:33














Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

– bremen_matt
Mar 27 at 9:35





Perhaps a more lengthy answer would be appropriate. There seems to be a subtlety here that I am missing.

– bremen_matt
Mar 27 at 9:35













I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

– Daniel H
Mar 28 at 2:05





I can't make a longer writeup now, and I can't find anything particularly good and not jargon-dense to link to. The gist is that constexpr data members worked more like other static data members, which need to be declared in the class and defined outside the class. The declaration could have the initialization in some cases (and has to for constexpr so the compiler can actually use it as a constant expression), but you still need the out-of-class definition.

– Daniel H
Mar 28 at 2:05








Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















draft saved

draft discarded
















































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%2f55372841%2flinkage-issues-when-using-a-static-constexpr-as-default-constructor-argument%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

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript