У меня есть некоторые путаницы в отношении переменных-членов static constexpr
в С++ 11.
В first.hpp
template<typename T>
struct cond_I
{ static constexpr T value = 0; };
// specialization
template<typename T>
struct cond_I< std::complex<T> >
{ static constexpr std::complex<T> value = {0,1}; };
В функции main()
cout << cond_I<double>::value << endl; // this works fine
cout << cond_I< complex<double> >::value << endl; // linker error
Однако, если я добавлю следующую строку в first.hpp
, все будет хорошо.
template<typename T1>
constexpr std::complex<T1> cond_I< std::complex<T1> >::value;
То, что я понимаю (возможно, ошибаюсь), заключается в том, что cond_I< std::complex<double> >::value
требуется определение, но в предыдущем случае оно имеет только объявление. Но тогда как насчет cond_I<double>::value
? Почему это не требует определения?
Опять же, в другом файле заголовка second.hpp
у меня есть:
В second.hpp
// empty struct
template<typename T>
struct eps
{ };
// special cases
template<>
struct eps<double>
{
static constexpr double value = 1.0e-12;
};
template<>
struct eps<float>
{
static constexpr float value = 1.0e-6;
};
В этом случае следующие коды отлично работают без определения eps<>::value
.
В функции main()
cout << eps<double>::value << endl; // works fine
cout << eps<float>::value << endl; // works fine
Может кто-нибудь объяснит мне разные типы поведения переменных static constexpr
в этих сценариях?
Эти поведения одинаковы для gcc-5.2
и clang-3.6
.