我希望有人澄清在哪种情况下使用static constexpr
作为类的构造函数的默认参数是安全的。要确切清除正在发生的情况,请考虑以下代码:
#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;
}
该代码似乎可以编译,但无法链接。具体来说,在使用GCC 6.3进行编译时,我得到
prog.cc:(.text+0x13): undefined reference to `Bar::default_options'
collect2: error: ld returned 1 exit status
但是,如果我们注释掉违规行,那么代码将正确编译,链接并运行。因此,假设使用static constexpr size_t
作为默认参数没有问题:
#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;
}
有人可以向我解释为什么链接对size_t
有效,而对array
无效吗?
我知道我可以这样定义内联的默认选项:
Bar(
Options options = std::array<Option, 0>{},
Option option = default_option
){
std::cout << "Constructed with option " << option << std::endl;
}
我只是想知道是否还有其他更好的修复程序,以便任何人都可以轻松查询默认选项。
答案 0 :(得分:2)
正如StoryTeller指出的那样,第一个代码确实可以编译并与C ++ 17和GCC 7.1+链接。为了使其能够与C ++ 11和旧版GCC一起编译,您需要数组的类外声明:
#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;
}