我是否需要在 else-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;
}

这非常简单-如果将 T推导为 int,我们希望返回 [a, 0.0]的元组。如果将 T推导为 double,我们希望返回 [0, a]的元组。否则,我们希望返回 [0, 0.0]

正如您所看到的,在 main()函数中,我使用 const char*参数调用 foo应该导致 xy0。这是 不是这个案子

在尝试编译它时,我遇到了一个奇怪的错误:

错误: 无法将‘ {0, a}’从‘ <brace-enclosed initializer list>’转换成‘ std::tuple<int, double>

我就像 什么?。究竟为什么我会想要... 我特别使用 std::is_same启用 return {0, a} 只有时,a的类型被推断为 double

因此,我迅速运行到 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;
}

我心想。

但我很好奇。我很好奇(当时)是否有什么奇怪的东西可以解决这个问题,所以我将原始代码改为:

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;
}

就是这样!按预期编译和执行的代码。所以,我的问题是-在这种情况下,我们是否需要在 ABC2语句中的每个 ABC1语句后面加上 constexpr还是它只是我的编译器?我正在使用海湾合作委员会7.3。

12322 次浏览

在这种情况下,是否需要在 if-else 块中的 every if 语句后面加上 conexpr?

是的。Else-if block 1是一个谎言:) ,只有 if block 1和 else block 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};
// }

else if (/*...*/)只是每个人都使用的格式约定。因此,您可以清楚地看到需要第二个 constexpr


1 : “ block”不是正确的术语。 if 是一个语句(带有可选的 else 部分)。 block 是 { /*...*/ }