Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ “static_assert”、“if constexpr(…)”和“constexpr”变量之间对模板中的“constexpr”lambdas的计算不一致_C++_Lambda_Constexpr_C++17_Constant Expression - Fatal编程技术网

C++ “static_assert”、“if constexpr(…)”和“constexpr”变量之间对模板中的“constexpr”lambdas的计算不一致

C++ “static_assert”、“if constexpr(…)”和“constexpr”变量之间对模板中的“constexpr”lambdas的计算不一致,c++,lambda,constexpr,c++17,constant-expression,C++,Lambda,Constexpr,C++17,Constant Expression,(使用g++7.0trunk。) 给定以下“类型到值包装”实用程序 template <typename T> struct type_wrapper { using type = T; }; // "Wraps" a type into a `constexpr` value. template <typename T> constexpr type_wrapper<T> type_c{}; 它也可以在静态断言中使用 static_assert(is_v

(使用
g++7.0
trunk。)

给定以下“类型到值包装”实用程序

template <typename T>
struct type_wrapper { using type = T; };

// "Wraps" a type into a `constexpr` value.
template <typename T>
constexpr type_wrapper<T> type_c{};
它也可以在
静态断言
中使用

static_assert(is_valid([](auto _0) constexpr -> decltype(_0.hello()){})
        (type_c<A>));

但是,当在模板函数中使用
is\u valid
时(将模板参数作为
type\u c
值传递),会发生一些奇怪的情况:

  • 静态断言(是否有效(/*…*/)
    工作正常

  • constexpr auto x=有效(/*…*/)
    工作正常

  • 如果constexpr(有效(/*…*/)
    编译失败

//按预期编译和工作。
模板
无效和0(T0,T1)
{
静态断言(
_是否有效([](自动_0,自动_1)constexpr
->decltype(0+1){})(类型c,类型c)
); 
}
//按照预期进行编译和工作。
模板
无效总和(T0,T1)
{
constexpr自动计算=
_是否有效([](自动_0,自动_1)constexpr
->decltype(0+1){})(类型c,类型c);
if constexpr(can_sum){}
}
//编译时错误!
模板
无效和失效0(T0,T1)
{
如果constexpr(是有效的([](自动0,自动1)constexpr
->decltype(0+1){})(类型_c,类型_c)){}
}
错误:

In function 'void sum_fail_0(T0, T1)':
64:95: error: expression '<lambda>' is not a constant expression
     if constexpr(is_valid([](auto _0, auto _1) constexpr -> decltype(_0 + _1){})(type_c<T0>, type_c<T1>)) { }
函数“无效和失败0(T0,T1)”中的

64:95:错误:表达式“”不是常量表达式
如果constexpr(是有效的([](自动0,自动1)constexpr->decltype(0+1){})(type_c,type_c)){}
如果constexpr(是否有效(/*…*/)情况下,
为什么无法仅为
编译?这与
静态断言和
constexpr auto x=/*…*/
不一致

这是
g++
实现
if constexpr
的一个缺陷吗


.

据我所知,lambda本身不是一个
constepr
。 你能行

constexpr auto f = [](auto _0, auto _1) -> decltype(_0 + _1){};
然后

if constexpr(is_valid(f)(type_c<T0>, type_c<T1>)) { }
如果constexpr(是有效的(f)(类型c,类型c)){

不一致的行为被报告为。

你重新发明了。@SamVarshavchik:不再是:)看起来肯定像个bug。即使明确地说
是有效的([](自动0,自动1)constexpr->decltype(_0+_1){
不会改变结果。为什么将lambda本身放入
constexpr
变量和
static\u assert
中会起作用,但如果constexpr
中则不会起作用?
// Compiles and works as intended.
template <typename T0, typename T1>
void sum_ok_0(T0, T1)
{
    static_assert(
         is_valid([](auto _0, auto _1) constexpr 
              -> decltype(_0 + _1){})(type_c<T0>, type_c<T1>)
    ); 
}

// Compiles and works as intended.
template <typename T0, typename T1>
void sum_ok_1(T0, T1)
{
    constexpr auto can_sum =
         is_valid([](auto _0, auto _1) constexpr 
              -> decltype(_0 + _1){})(type_c<T0>, type_c<T1>); 

    if constexpr(can_sum) { }
}

// Compile-time error!
template <typename T0, typename T1>
void sum_fail_0(T0, T1)
{
    if constexpr(is_valid([](auto _0, auto _1) constexpr 
         -> decltype(_0 + _1){})(type_c<T0>, type_c<T1>)) { } 
}
In function 'void sum_fail_0(T0, T1)':
64:95: error: expression '<lambda>' is not a constant expression
     if constexpr(is_valid([](auto _0, auto _1) constexpr -> decltype(_0 + _1){})(type_c<T0>, type_c<T1>)) { }
constexpr auto f = [](auto _0, auto _1) -> decltype(_0 + _1){};
if constexpr(is_valid(f)(type_c<T0>, type_c<T1>)) { }