Do I need to put constexpr after else-if?(我需要将 constexpr 放在 else-if 之后吗?)
问题描述
受到这个答案的启发,我尝试复制和粘贴(并在main()中添加测试) 这段代码:
Inspired by this answer, I tried to copy and paste (and add testing in main()) this code:
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].
This is very straightforward - if T is deduced as int, we want to return a tuple of [a, 0.0]. If T is deduced as double, we want to return a tuple of [0, a]. Otherwise, we want to return [0, 0.0].
如您所见,在 main() 函数中,我使用 const char* 参数调用 foo,其中 应该导致 x 和 y 为 0.事实并非如此.
As you can see, in the main() function, I am calling foo with const char* argument, which should result in x and y being 0. That is not the case.
在尝试编译时,我遇到了一个奇怪的错误:
While trying to compile it, I encountered a strange error:
错误:无法将 '{0, a}' 从 '' 转换为 'std::tuple<;int, double>'
error: could not convert '
{0, a}' from '<brace-enclosed initializer list>' to 'std::tuple<int, double>'
而我就像什么?.我到底为什么要这样......我专门使用 std::is_same 来启用 return {0, a} only 当类型a 的推导为 double.
And I was like what?. Why on earth would I want that... I specifically used std::is_same to enable return {0, a} only when the type of a is deduced as double.
所以我很快就在 if-constexpr 上跑到 cppreference.在页面底部,注释上方,我们可以看到这段代码:
So I quickly ran to cppreference on if-constexpr. At the bottom of the page, above Notes, we can see this snippet of code:
extern int x; // no definition of x required
int f() {
if constexpr (true)
return 0;
else if (x)
return x;
else
return -x;
}
我心想哎呀..?我真的看不出原始代码有什么问题.它们使用相同的语法和语义....
但是我很好奇.我很好奇是否有一些奇怪的东西(当时)可以解决这个问题,所以我将原始代码更改为:
But I was curious. I was curious if maybe something odd (at that time) might fix that issue, so I changed the original code to:
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.
And voilà! The code compiled and executed as expected. So, my question is - Do we need to put constexpr after every if statement in if-else statement in these kind of situations? Or is it just my compiler? I am using GCC 7.3.
推荐答案
在这种情况下,我们是否需要在 if-else 块中的每个 if 语句之后放置 constexpr?
Do we need to put constexpr after every if statement in if-else block in these kind of situations?
是的.else-if block1 是个谎言:),只有 if blocks1 和 else blocks1.这是编译器看到您的代码的方式:
Yes. The else-if block1 is a lie :), there are only if blocks1 and else blocks1. This is how your code is seen by the compiler:
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.
else if (/*...*/) is just a formatting convention that everyone uses. As such, you can clearly see that the second constexpr is needed.
1:块"不是正确的术语.if 是一个语句(带有可选的 else 部分).一个块是 {/*...*
本文标题为:我需要将 constexpr 放在 else-if 之后吗?
基础教程推荐
- 常量变量在标题中不起作用 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 我有静态或动态 boost 库吗? 2021-01-01
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- C++结构和函数声明。为什么它不能编译? 2022-11-07
