Проблема в том, что когда пишешь
WeakVar() {
if(std::is_pointer<TypeLD>::value)
ld_ = new long double(0); // error: cannot convert 'long double*' to 'TypeLD'{aka 'long double'}
else
ld_ = 0;
}
компилятор должен скомпилировать оба случая if()
То есть, когда TypeLD
не является указателем, компилятор должен скомпилировать
ld_ = new long double(0);
Решение: если (когда) вы можете использовать C ++ 17 или новее, используйте if constexpr
if constexpr (std::is_pointer<TypeLD>::value)
ld_ = new long double(0);
else
ld_ = 0;
, который введен именно для того, чтобы не компилировать неправильный код, когда значение теста известно во время компиляции.
В противном случае (в C ++ 11 и C ++ 14) вы можете написать две разные функции и, используя SFINAE, включить правильную.
Примером (осторожно: код не проверен)
template <typename T = TypeLD,
typename std::enable_if<true == std::is_pointer<T>::value, bool>::type = true>
WeakVar () : ld_{new long double(0)}
{ }
template <typename T = TypeLD,
typename std::enable_if<false == std::is_pointer<T>::value, bool>::type = true>
WeakVar () : ld_{0}
{ }
Я пытался создавать сеттеры с помощью std :: enable_if, но безрезультатно ...
Это связано с тем, что SFINAE для включения / отключения метода класса работает только с шаблонными методами с тестами по шаблонным параметрам самого метода, а не по шаблонным параметрам класса.
Итак, в приведенном выше примере я написал
template <typename T = TypeLD,
typename std::enable_if<true == std::is_pointer<T>::value, bool>::type = true>
, поэтому тест включения / выключения относится к типу имени T
, параметру шаблона конструктора, а не к TypeLD
, параметру шаблона полного класса.
Если вы напишите
template <typename std::enable_if<true == std::is_pointer<TypeLD>::value, bool>::type = true>
вы получите ошибку.