Я бы хотел, чтобы кто-нибудь разъяснил, в каких случаях безопасно использовать 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;
}
Мне просто было интересно, есть ли какое-нибудь более приятное исправление, чтобы параметры по умолчанию могли быть легко запрошены кем-либо.