это даже не утверждение. Это половина одного.
овленэтот ответЯ попытался скопировать и вставить (и добавить тестирование вmain()
) этот код:
template<typename T>
std::tuple<int, double> foo(T a) {
if constexpr (std::is_same_v<int, T>)
return {a, 0.0};
else if (std::is_same_v<double, T>)
return {0, a};
else
return {0, 0.0};
}
int main()
{
auto [x, y] = foo("");
std::cout << x << " " << y;
}
Это очень просто - еслиT
выводится какint
мы хотим вернуть кортеж[a, 0.0]
, ЕслиT
выводится какdouble
мы хотим вернуть кортеж[0, a]
, В противном случае мы хотим вернуть[0, 0.0]
.
Как вы можете видеть, вmain()
функция, я звонюfoo
с участиемconst char*
аргумент, которыйдолжен результат вx
а такжеy
являющийся0
, Этоне тот случай.
При попытке скомпилировать я столкнулся со странной ошибкой:
ошибка: не удалось преобразовать{0, a}
' из '<brace-enclosed initializer list>
кstd::tuple<int, double>
'
И я был какчто?, С какой стати я хочу этого ... Я специально использовалstd::is_same
включитьreturn {0, a}
только когда типa
выводится какdouble
.
Поэтому я быстро побежал кcppreference на if-constexpr. Внизу страницы вышеПримечаниямы можем увидеть этот фрагмент кода:
extern int x; // no definition of x required
int f() {
if constexpr (true)
return 0;
else if (x)
return x;
else
return -x;
}
я подумал про себяoookay ..? Я не могу понять, что не так с оригинальным кодом. Они используют тот же синтаксис и семантику ....
Но мне было любопытно. Мне было любопытно, может ли что-то странное (в то время) решить эту проблему, поэтому я изменил исходный код на:
template<typename T>
std::tuple<int, double> foo(T a) {
if constexpr (std::is_same_v<int, T>)
return {a, 0.0};
else if constexpr (std::is_same_v<double, T>) // notice the additional constexpr here
return {0, a};
else
return {0, 0.0};
}
int main()
{
auto [x, y] = foo("");
std::cout << x << " " << y;
}
И вуаля! Код скомпилирован и выполнен как ожидалось. Итак, мой вопрос -Нужно ли ставитьconstexpr
после каждогоif
заявление вif-else
заявление в подобных ситуациях? Или это только мой компилятор? Я использую GCC 7.3.