灵感来自这个答案 https://stackoverflow.com/a/52355930/7151494,我尝试复制并粘贴(并在中添加测试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]
. If T
推导为double
,我们想要返回一个元组[0, a]
。否则,我们想返回[0, 0.0]
.
如您所见,在main()
函数,我正在调用foo
with const char*
论证,其中should导致x
and y
being 0
。那是事实并非如此.
在尝试编译它时,我遇到了一个奇怪的错误:
错误:无法转换'{0, a}
' from '<brace-enclosed initializer list>
' to 'std::tuple<int, double>
'
我当时就像what?。我到底为什么想要那个...我专门用过std::is_same
启用return {0, a}
only当类型为a
推导为double
.
于是我赶紧跑去参考参数 https://en.cppreference.com/w/cpp/language/if在 if-constexpr 上。在页面底部、上方Notes,我们可以看到这段代码:
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;
}
瞧!代码按预期编译并执行。所以,我的问题是 -我们需要把constexpr
每次之后if
中的声明if-else
在这种情况下的声明?或者只是我的编译器?我正在使用海湾合作委员会7.3。