【发布时间】:2019-02-20 16:55:47
【问题描述】:
受this answer 的启发,我尝试复制并粘贴(并在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,这应该导致x 和y 成为0。 情况并非如此。
在尝试编译时,我遇到了一个奇怪的错误:
错误:无法将“
{0, a}”从“<brace-enclosed initializer list>”转换为“std::tuple<int, double>”
而我就像什么?。我到底为什么要那样...我专门使用std::is_same 来启用return {0, a} 仅 当a 的类型被推断为double。
所以我在 if-constexpr 上迅速跑到 cppreference。在页面底部,Notes上方,我们可以看到这段sn-p的代码:
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;
}
然后瞧!代码按预期编译和执行。所以,我的问题是 - 在这种情况下,我们是否需要在 if-else 语句中的每个 if 语句之后放置 constexpr? 还是只是我的编译器?我正在使用 GCC 7.3。
【问题讨论】:
标签: c++ if-statement c++17 if-constexpr