Fur*_*ish 37 c++ if-statement c++17 if-constexpr
受此答案的启发,我尝试复制并粘贴(并添加测试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;
}
Run Code Online (Sandbox Code Playgroud)
这非常简单 - 如果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} adouble
所以我很快就找到了if-constexpr的cppreference.在页面底部的Notes上方,我们可以看到以下代码片段:
extern int x; // no definition of x required
int f() {
if constexpr (true)
return 0;
else if (x)
return x;
else
return -x;
}
Run Code Online (Sandbox Code Playgroud)
我心想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;
}
Run Code Online (Sandbox Code Playgroud)
瞧!代码按预期编译和执行.所以,我的问题是 - 在这种情况下,我们是否需要在声明中的constexpr每个if陈述之后加上if-else?或者只是我的编译器?我正在使用GCC 7.3.
Rak*_*111 50
在这种情况下,我们是否需要在if-else块中的每个if语句之后放置constexpr?
是.else-if块1是谎言:),只有块1和其他块1.这就是编译器看到代码的方式:
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};
// }
Run Code Online (Sandbox Code Playgroud)
else if (/*...*/)只是每个人都使用的格式约定.因此,您可以清楚地看到第二个constexpr是必需的.
1:"阻止"不是正确的术语.if是一个语句(带有可选的else部分).一块是{ /*...*/ }.