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.
Aucun commentaire:
Enregistrer un commentaire