最佳答案
受到 这个答案的启发,我尝试复制和粘贴(并在 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 上的 首选。在页面的底部,在 笔记上面,我们可以看到这段代码:
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。