标签: if-constexpr

"constexpr if"vs"if"with optimizations - 为什么需要"constexpr"?

C++ 1z将引入"constexpr if" - 如果将根据条件删除其中一个分支.似乎合理有用.

但是,没有constexpr关键字是不可能的?我认为在编译期间,编译器应该知道编译时间是否已知.如果是,即使是最基本的优化级别也应该删除不必要的分支.

例如(参见godbolt:https://godbolt.org/g/IpY5y5 ):

int test() {
    const bool condition = true;
    if (condition) {
      return 0;
    } else {
      // optimized out even without "constexpr if"
      return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

Godbolt探险家表示,即使是带有-O0的gcc-4.4.7也没有编译"返回1",所以它实现了constexpr所承诺的.显然,当条件是constexpr函数的结果时,这样的旧编译器将无法这样做,但事实仍然存在:现代编译器知道条件是否为constexpr,并且不需要我明确地告诉它.

所以问题是:

为什么"constexpr if"需要"constexpr"?

c++ constexpr c++17 if-constexpr

39
推荐指数
1
解决办法
1455
查看次数

为什么这个"未定义的外部变量"不会导致C++ 17中的链接器错误?

我已经在C++ 17编译器(Coliru)中编译并运行了以下程序.在程序中,我声明了一个extern变量,但没有定义它.但是,编译器不会给出链接器错误.

#include <iostream>

extern int i; // Only declaration

int func() 
{
    if constexpr (true)
        return 0;
    else if (i)
        return i;
    else
        return -1;
}

int main() 
{
    int ret = func();
    std::cout<<"Ret : "<<ret<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器没有给出链接器错误?

c++ linker-errors extern c++17 if-constexpr

38
推荐指数
3
解决办法
3695
查看次数

我需要把constexpr放在其他地方 - 如果?

受此答案的启发,我尝试复制并粘贴(并添加测试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;
}
Run Code Online (Sandbox Code Playgroud)

这非常简单 - 如果T推断为int,我们想要返回一个元组[a, 0.0].如果T推断为double,我们想要返回一个元组 [0, a].否则,我们想要回来[0, 0.0].

正如你所看到的,在main()函数中,我fooconst char*参数调用,这应该导致x和 …

c++ if-statement c++17 if-constexpr

37
推荐指数
1
解决办法
2525
查看次数

为什么没有if constexpr使这个核心常量表达式错误消失?

参考这个问题.用于初始化constexpr变量的核心常量表达式是错误的y.这么多是给定的.

但如果我试着if变成if constexpr:

template <typename T>
void foo() {
    constexpr int x = -1;
    if constexpr (x >= 0){
        constexpr int y = 1 << x;
    }
}

int main(){
    foo<int>();
}
Run Code Online (Sandbox Code Playgroud)

错误仍然存​​在.GCC 7.2仍然给出:

error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

但我认为语义检查应该在废弃的分支上保持不成形.

constexpr但是,通过lambda 进行间接确实有帮助:

template <typename T>
void foo(){
    constexpr int x = -1;
    constexpr auto p = []() constexpr { return x; }; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer constexpr c++17 if-constexpr

31
推荐指数
3
解决办法
1475
查看次数

constexpr的等效三元运算符if?

也许我错过了一些东西,但我找不到任何提示:C++ 17中有一个constexpr三元运算符,相当于constexpr-if?

template<typename Mode>
class BusAddress {
public:
    explicit constexpr BusAddress(Address device) : 
        mAddress(Mode::write ? (device.mDevice << 1) : (device.mDevice << 1) | 0x01) {}
private:
    uint8_t mAddress = 0;    
};
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++17 if-constexpr

27
推荐指数
2
解决办法
2970
查看次数

我如何在if-constexpr中使用概念?

如何使用概念if constexpr

给出下面的例子,if constexpr如果T满足要求,则返回1 将给予integral什么?

template<typename T>
concept integral = std::is_integral_v<T>;

struct X{};

template<typename T>
constexpr auto a () {
    if constexpr (/* T is integral */) {
        return 1;
    } 
    else {
        return 0;
    }
}

int main () {
    return a<X>();
}
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20 if-constexpr

27
推荐指数
2
解决办法
1146
查看次数

'if constexpr branch'不会在模板函数内部的lambda内部被丢弃

如下代码

#include <type_traits>

struct X {
    static constexpr void x() {}
};

template <class T1, class T2>
constexpr bool makeFalse() { return false; }

template <class T>
void foo() {
    T tmp;
    auto f = [](auto type) {
        if constexpr (makeFalse<T, decltype(type)>()) {
            T::x(); // <- clang does not discard
        } else {
            // noop
        }
    };
}

int main() {
    foo<int>();
}
Run Code Online (Sandbox Code Playgroud)

不使用Clang编译,但是使用GCC编译。我看不到这段代码有什么问题,但是我不确定。Clang对吗?

c++ c++17 if-constexpr

27
推荐指数
1
解决办法
525
查看次数

C ++检查语句是否可以评估为constexpr

有没有一种方法可以确定是否可以对constexpr求值,并将结果用作constexpr布尔值?我的简化用例如下:

template <typename base>
class derived
{
    template<size_t size>
    void do_stuff() { (...) }

    void do_stuff(size_t size) { (...) }
public:
    void execute()
    {
        if constexpr(is_constexpr(base::get_data())
        {
            do_stuff<base::get_data()>();
        }
        else
        {
            do_stuff(base::get_data());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的目标是C ++ 2a。

我发现了以下reddit线程,但我不是宏的忠实拥护者。https://www.reddit.com/r/cpp/comments/7c208c/is_constexpr_a_macro_that_check_if_an_expression/

c++ template-meta-programming constexpr c++20 if-constexpr

23
推荐指数
3
解决办法
1291
查看次数

在通用lambda中使用`if constexpr`访问成员类型需要两个分支都是格式良好的 - gcc vs clang

考虑两个struct具有不同成员类型别名的s:

struct foo { using x = int;   };
struct bar { using y = float; };
Run Code Online (Sandbox Code Playgroud)

给定Ttemplate情况下,我想无论是T::x还是T::y取决于什么T是:

template <typename T>
auto s()
{
    auto l = [](auto p) 
    {
        if constexpr(p) { return typename T::x{}; }
        else            { return typename T::y{}; }
    };

    return l(std::is_same<T, foo>{});
}

int main() 
{ 
    s<foo>(); 
}
Run Code Online (Sandbox Code Playgroud)

g++编译上面的代码,同时clang++产生这个错误:

error: no type named 'y' in 'foo'
        else            { return typename …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae language-lawyer c++17 if-constexpr

19
推荐指数
1
解决办法
363
查看次数

在lambda内部捕获的Constexpr变量失去了其解释性

这段代码可以在g ++(coliru)中很好地编译,但是在MSVC(Godbolt和我的VS2017)中却不能。

#include <type_traits>
#include <iostream>
template<class T> void f(){
    constexpr bool b=std::is_same_v<T,int>; //#1
    auto func_x=[&](){
        if constexpr(b){ //#error
        }else{
        }
    };
    func_x();
}
int main(){
    f<int>();
}
Run Code Online (Sandbox Code Playgroud)

(6):错误C2131:表达式未求值为常数
(6):注意:失败是由于在其生命周期之外读取变量导致的
(6):注意:请参见'this'的用法

哪一个(g ++或MSVC)错了?“ 请参阅'this'的用法
是什么??this

在保留编译时保证的同时如何解决呢?

在我的真实情况下,b (#1)一个复杂的语句取决于其他一些constexpr变量。

c++ lambda language-lawyer c++17 if-constexpr

19
推荐指数
2
解决办法
867
查看次数