嵌套的从属名称不在概念模板中评估
Nested dependent names are not evaluated in template for concept
(最初与分开。)
在下面的代码片段中,
#include <concepts>
template<
typename T,
typename value_type = typename T::value_type
>
concept check_type = std::default_initializable<T>;
struct Foo {};
template<check_type T>
void func(T t) {}
int main()
{
Foo foo;
func(foo);
}
struct Foo
不包含类型别名 value_type
但它使用 GCC 编译时没有错误。
参见result tested on the compiler explorer。
但是,对于 Clang,它会报告以下错误消息:
❯ clang++ -std=c++20 asdf.cpp
asdf.cpp:17:5: error: no matching function for call to 'func'
func(foo);
^~~~
asdf.cpp:12:6: note: candidate template ignored: constraints not satisfied [with T = Foo]
void func(T t) {}
^
asdf.cpp:5:39: note: because substituted constraint expression is ill-formed: no type named 'value_type' in 'Foo'
typename value_type = typename T::value_type
^
1 error generated.
另见 result tested on the compiler explorer。
这是一个错误吗?
GCC 在当前措辞下是正确的。
根据 [temp.deduct]/5,对函数模板的 关联约束 进行满意度检查:
If the function template has associated constraints ([temp.constr.decl]), those constraints are checked for satisfaction ([temp.constr.constr]).
[temp.constr.decl]/3.2指定关联约束基于范式:
A declaration's associated constraints are defined as follows:
- ...
- Otherwise, if there is a single introduced
constraint-expression, the associated constraints are the normal form
of that expression.
由于check_type
是一个概念,它对规范化([temp.constr.normal]/1.4)是透明的,并且由于check_type
的第二个模板参数没有在它的定义中使用,所以那个参数确实不会出现在约束表达式的正常形式中。因此,T::value_type
的有效性(或缺乏有效性)对满意度检查没有影响。
如果你想让这个概念检查 value_type
,直接检查 value_type
更具有表现力(更不用说正确了):
template <typename T>
concept check_type = std::default_initializable<T> && requires { typename T::value_type; };
(最初与
在下面的代码片段中,
#include <concepts>
template<
typename T,
typename value_type = typename T::value_type
>
concept check_type = std::default_initializable<T>;
struct Foo {};
template<check_type T>
void func(T t) {}
int main()
{
Foo foo;
func(foo);
}
struct Foo
不包含类型别名 value_type
但它使用 GCC 编译时没有错误。
参见result tested on the compiler explorer。
但是,对于 Clang,它会报告以下错误消息:
❯ clang++ -std=c++20 asdf.cpp
asdf.cpp:17:5: error: no matching function for call to 'func'
func(foo);
^~~~
asdf.cpp:12:6: note: candidate template ignored: constraints not satisfied [with T = Foo]
void func(T t) {}
^
asdf.cpp:5:39: note: because substituted constraint expression is ill-formed: no type named 'value_type' in 'Foo'
typename value_type = typename T::value_type
^
1 error generated.
另见 result tested on the compiler explorer。
这是一个错误吗?
GCC 在当前措辞下是正确的。
根据 [temp.deduct]/5,对函数模板的 关联约束 进行满意度检查:
If the function template has associated constraints ([temp.constr.decl]), those constraints are checked for satisfaction ([temp.constr.constr]).
[temp.constr.decl]/3.2指定关联约束基于范式:
A declaration's associated constraints are defined as follows:
- ...
- Otherwise, if there is a single introduced constraint-expression, the associated constraints are the normal form of that expression.
由于check_type
是一个概念,它对规范化([temp.constr.normal]/1.4)是透明的,并且由于check_type
的第二个模板参数没有在它的定义中使用,所以那个参数确实不会出现在约束表达式的正常形式中。因此,T::value_type
的有效性(或缺乏有效性)对满意度检查没有影响。
如果你想让这个概念检查 value_type
,直接检查 value_type
更具有表现力(更不用说正确了):
template <typename T>
concept check_type = std::default_initializable<T> && requires { typename T::value_type; };