我需要在 else-if 之后放置 constexpr 吗?
Do I need to put constexpr after else-if?
受到的启发,我尝试复制粘贴(并在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
,我们想要return一个[a, 0.0]
的元组。如果T
被推导为double
,我们想要return一个[0, a]
的元组。否则,我们要 return [0, 0.0]
.
如您所见,在 main()
函数中,我使用 const char*
参数调用 foo
, 应该 导致 x
和 y
是 0
。那是不是这样。
在尝试编译时,我遇到了一个奇怪的错误:
error: could not convert '{0, a}
' from '<brace-enclosed initializer list>
' to 'std::tuple<int, double>
'
我当时想 什么?。我到底为什么要那个...我专门使用 std::is_same
来启用 return {0, a}
只有 当 a
的类型被推断为 double
.
所以我很快 运行 cppreference 在 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;
}
瞧!代码按预期编译和执行。所以,我的问题是 - 在这种情况下,我们是否需要在 if-else
语句中的每个 if
语句之后放置 constexpr
? 或者是只是我的编译器?我正在使用 GCC 7.3。
Do we need to put constexpr after every if statement in if-else block in these kind of situations?
是的。 else-if块1是个谎言:),只有if块1和else块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 部分)。一个块是{ /*...*/ }
.
受到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
,我们想要return一个[a, 0.0]
的元组。如果T
被推导为double
,我们想要return一个[0, a]
的元组。否则,我们要 return [0, 0.0]
.
如您所见,在 main()
函数中,我使用 const char*
参数调用 foo
, 应该 导致 x
和 y
是 0
。那是不是这样。
在尝试编译时,我遇到了一个奇怪的错误:
error: could not convert '
{0, a}
' from '<brace-enclosed initializer list>
' to 'std::tuple<int, double>
'
我当时想 什么?。我到底为什么要那个...我专门使用 std::is_same
来启用 return {0, a}
只有 当 a
的类型被推断为 double
.
所以我很快 运行 cppreference 在 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;
}
瞧!代码按预期编译和执行。所以,我的问题是 - 在这种情况下,我们是否需要在 if-else
语句中的每个 if
语句之后放置 constexpr
? 或者是只是我的编译器?我正在使用 GCC 7.3。
Do we need to put constexpr after every if statement in if-else block in these kind of situations?
是的。 else-if块1是个谎言:),只有if块1和else块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 部分)。一个块是{ /*...*/ }
.