如果不是,是否需要在constexpr之后放? [英] Do I need to put constexpr after else-if?

查看:139
本文介绍了如果不是,是否需要在constexpr之后放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此答案的启发,我试图复制并粘贴(并在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,该应该导致xy0.情况并非如此.

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}"从"<brace-enclosed initializer list>"转换为"std::tuple<int, double>"

error: could not convert '{0, a}' from '<brace-enclosed initializer list>' to 'std::tuple<int, double>'

我就像什么?.我到底为什么要......当a的类型推导为double时,我专门使用std::is_same启用return {0, a} .

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.

推荐答案

在这种情况下,是否需要将constexpr放在if-else块中的每个if语句之后?

Do we need to put constexpr after every if statement in if-else block in these kind of situations?

是的. else-if块 1 是一个谎言:),仅当blocks 1 和else块 1 时才存在.这是编译器如何看待您的代码:

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部分).阻止为{ /*...*/ }.

1: "block" is not the correct terminology. if is a statement (with optional else part). A block is { /*...*/ }.

这篇关于如果不是,是否需要在constexpr之后放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆