标签: if-constexpr

可以`if constexpr`用于声明具有不同类型和init-expr的变量

例如:

void foo()
{
    if constexpr (...)
        int x = 5;
    else
        double x = 10.0;
    bar(x); // calls different overloads of bar with different values
}
Run Code Online (Sandbox Code Playgroud)

这是D lang的常见情况,但我没有找到有关C++ 17的信息.

当然,可以使用类似的东西

std::conditional<..., int, double>::type x;
Run Code Online (Sandbox Code Playgroud)

但仅限于基本情况.即使是不同的初始化者(如上所述)也会产生很大的问题.

c++ metaprogramming c++17 if-constexpr

8
推荐指数
1
解决办法
853
查看次数

如果 constexpr 没有被丢弃,Static_assert 在里面

static_assert在 的 false 分支中应丢弃以下内容if constexpr,但由于断言失败而导致编译失败:

#include <type_traits>                                                                                                                                                                              

template <class T>                                                                                                                                                                                  
constexpr bool f() {                                                                                                                                                                                
  if constexpr (std::is_same<T, int>::value) return true;                                                                                                                                                                                                                                                                    
  else static_assert(false, "message");                                                                                                                                                             
}                                                                                                                                                                                                   

int main () {                                                                                                                                                                                       
  if constexpr (f<int>()) return 1;                                                                                                                                                                 
  return 0;                                                                                                                                                                                         
} 
Run Code Online (Sandbox Code Playgroud)

我希望丢弃的分支if constexpr不会被评估,因为它f是用 type 实例化的int

用 Gcc 7.2 (-std=c++17) 编译

c++ instantiation static-assert constexpr if-constexpr

8
推荐指数
0
解决办法
1868
查看次数

MSVC使用constexpr if在可变参数模板方法中吞下const的基本模板参数

我有一个问题,我几乎可以肯定是一个MSVC错误,但也许我错过了一些东西.

这是实际代码的简化版本:

template <typename... Args>
class InnerType {};

template <typename... Args>
class OuterType {
public:
    void foo1() {
        if constexpr (true) {
            bar(InnerType<Args...>());
        }
    }

    void foo2() {
        if (true) {
            bar(InnerType<Args...>());
        }
    }

    void bar(InnerType<Args...>) {}
};
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,唯一的区别foo1()foo2()是constexpr如果.当我尝试在MSVC中编译一些测试时会发生以下情况:

 OuterType<const bool> test1;
 test1.foo1(); // does not compile
 test1.foo2(); // compiles

 OuterType<bool> test2;
 test2.foo1(); // compiles
 test2.foo2(); // compiles
Run Code Online (Sandbox Code Playgroud)

我得到的错误test1.foo1()是:

error C2664: 'void OuterType<const bool>::bar(InnerType<const bool>)':
cannot convert argument 1 from 'InnerType<bool>' to 'InnerType<const bool>' …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ variadic-templates if-constexpr

8
推荐指数
1
解决办法
74
查看次数

您自己的类型的结构化绑定,不是结构或元组(通过公共成员函数)

我正在经历Herb Scutter的

旅程:走向更强大,更简单的C++编程

结构绑定部分

为了理解这个概念.Best是编写一个我试过的程序,但是遇到了一些错误

只是想尝试如何在类上使用私有数据的结构绑定.请忽略下面的示例.如果您能提供任何示例

#include<iostream>
#include<string>
using namespace std;

class foobar {
public:
    foobar() { cout << "foobar::foobar()\n"; }
    ~foobar() { cout << "foobar::~foobar()\n"; }

    foobar( const foobar &rhs )
    { cout << "foobar::foobar( const foobar & )\n"; }
    void ival( int nval, string new_string ) { _ival = nval;s=new_string; }

private:
    int _ival;
    string s;
};

foobar f( int val,string new_string ) {
    foobar local;
    local.ival( val,new_string );
    return local;
}

template<> struct tuple_element<0,foobar> { using …
Run Code Online (Sandbox Code Playgroud)

c++ stdtuple c++17 structured-bindings if-constexpr

7
推荐指数
2
解决办法
1553
查看次数

"如果constexpr"与"尝试constexpr功能"警告相互作用

我声称这个程序应该是格式良好的:它声明了一个constexpr成员函数S<int>.但是,GCC和Clang都拒绝接受这个计划.

template<class T>
struct S {
    constexpr int foo() {
        if constexpr (std::is_same_v<T, int>) {
            return 0;
        } else {
            try {} catch (...) {}
            return 1;
        }
    }
};

int main()
{
    S<int> s;
    return s.foo();  // expect "return 0"
}
Run Code Online (Sandbox Code Playgroud)

GCC说:

错误:'constexpr'功能'尝试'

Clang说:

错误:constexpr函数中不允许使用语句

他们似乎都没有注意到"try"语句位于语句的废弃分支中if constexpr.

如果我将try/ catchout分解为非constexpr成员函数void trycatch(),那么Clang和GCC都会再次对代码感到满意,即使它的行为应该等同于不满意的版本.

template<class T>
struct S {
    void trycatch() {
        try {} catch (...) {}
    }
    constexpr int …
Run Code Online (Sandbox Code Playgroud)

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

7
推荐指数
1
解决办法
465
查看次数

"if constexpr"在模板之外有用吗?

我想if constexpr完全理解.

我理解,如果if constexpr(expr)在模板中使用,并且expr依赖于模板参数,那么在实例化期间,只有一个then/ else分支将被实例化,另一个将被丢弃.

我有两个问题:

  • 是真的,如果expr不依赖于模板参数,那么if constexpr(expr)将不会丢弃任何分支?如果是,标准在哪里这样说?我没有看到标准有什么例外,丢弃只在expr依赖时发生.
  • if constexpr模板以外有用吗?如果是,这有什么用例?你能举出一些例子来了解它的用处吗?

c++ constexpr c++17 if-constexpr template-instantiation

7
推荐指数
1
解决办法
255
查看次数

if constexpr 内部使用 static_assert 格式良好吗?

我昨天读了几个关于在an 子句中使用的答案。我知道根据标准,它被认为是格式错误的(即使某些编译器,包括 MSVC2017,会接受它)。Qt 也会将此标记为错误。static_assert(false, "Some message")elseif constexpr

我的问题是,下面的代码是否符合标准?(我倾向于这么认为,但我想确认一下。)

template <typename TypeOfValue>
static void PushValue(duk_context* ctx, TypeOfValue value) {
    // Push value onto duktape stack
    if constexpr (std::is_same<TypeOfValue, int>::value) {
        // Push int
        duk_push_int(ctx, value);
    } else if constexpr (std::is_same<TypeOfValue, uint32_t>::value) {
        // Push uint
        duk_push_uint(ctx, value);
    } else {
        // Unsupported type
        static_assert(bool_value<false, TypeOfValue>(), "Unsupported type");
    }    
}

template <bool value, typename T>
static constexpr bool bool_value() {return value;}        
Run Code Online (Sandbox Code Playgroud)

编辑: …

c++ static-assert language-lawyer constexpr if-constexpr

7
推荐指数
1
解决办法
1348
查看次数

可能的模板和constexpr - 如果不兼容

我想e在编译时计算价值(不用担心,不是作业),但出了点问题.

template<size_t limit = 3, class result = std::ratio<0, 1>, size_t factorial = 1, size_t count = 1>
constexpr double e_impl() {
    if constexpr(limit == 0) {
        return static_cast<double>(result{}.num) / result{}.den;
    }
    return e_impl<limit - 1, std::ratio_add<result, std::ratio<1, factorial>>, factorial * count, count + 1>();
}
Run Code Online (Sandbox Code Playgroud)

虽然计算值是正确的,但编译器会抛出有关模板溢出的错误.似乎limit变量超出范围(下面0),但它不应该发生,因为0-case由if constexpr(…)语句处理.

所以问题是,我错了,应该预期这种行为,还是编译错误?用GCC 7.1.0编译.

c++ templates constexpr if-constexpr

6
推荐指数
2
解决办法
210
查看次数

如何决定constexpr返回参考

如果您有一个if constexpr ()决定做一件事或另一件事的函数,那么在一种情况下如何返回左值,在另一种情况下如何返回右值?

以下示例不会在第一个用法行中编译,因为返回类型auto为无引用:

static int number = 15;

template<bool getref>
auto get_number(int sometemporary)
{
    if constexpr(getref)
    {
        return number; // we want to return a reference here
    }
    else
    {
        (...) // do some calculations with `sometemporary`
        return sometemporary;
    }
}

void use()
{
    int& ref = get_number<true>(1234);
    int noref = get_number<false>(1234);
}
Run Code Online (Sandbox Code Playgroud)

c++ constexpr auto c++17 if-constexpr

6
推荐指数
1
解决办法
147
查看次数

如果constexpr位于lambda中,则编译器行为不同

考虑以下代码。如果我的理解if constexpr是正确的,则else不应编译分支,因此z()不应将其视为错误。

#include <type_traits>

struct Z{};

template<typename T>
void f(T z) {
  auto lam = [z]() {
    if constexpr(std::is_same<T, Z>::value) {
    } else {
      z();
    }
  };
}

int main() {
  f(Z{});
}
Run Code Online (Sandbox Code Playgroud)

clanggcc编译;但是使用最新的MSVC却没有。不幸的是,goldbolt的MSVC太旧了,但是在我的计算机上使用VS 2017进行了全面更新,结果是cl /std:c++17

Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

if_constexpr.cpp
if_constexpr.cpp(10): error C2064: term does not evaluate to a function taking 0 arguments
if_constexpr.cpp(16): note: …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++17 if-constexpr

5
推荐指数
1
解决办法
228
查看次数