默认模板参数中的lambda是否被视为即时上下文的一部分?

时间:2018-12-03 13:45:37

标签: c++ language-lawyer c++17

以下代码格式正确的C ++ 17吗?

template <typename T, int = [](auto t) { decltype(t)::invalid; return 0; }(T{})>
constexpr int f(T) { return 0; }
constexpr int f(...) { return 1; }

static_assert(f(0) == 1);

clang和edg接受它,而msvc和gcc 1 拒绝它。我找不到任何可以说这是一个硬错误的信息,但是我也找不到任何可以说这是推论失败的信息。

在C ++ 20中,有以下段落([temp.deduct]p9):

  

出于模板自变量推导的目的,在函数类型或模板参数中出现的 lambda-表达式不被视为立即上下文的一部分。

可以很清楚地知道,lambda不是立即上下文的一部分。但是C ++ 17呢?


1 :在这种情况下,gcc在auto中存在一个错误,但是使用用于lambda的显式模板参数重写它会遇到相同的错误。

1 个答案:

答案 0 :(得分:12)

如果我正确收集的话,它在C ++ 17中是格式错误的

  

[expr.prim.lambda] (强调我的意思)

     

2 Lambda表达式不得出现在未评估的操作数中,   在模板参数中,[...]

     

[temp.param] (强调我的意思)

     

9默认模板参数是模板参数   ([temp.arg])在模板参数中的=之后指定。

在两种情况下,“模板参数”都是相同的规范术语。因此,我认为Clang和edg err将OP中的代码接受为有效的C ++ 17。