gpt4 book ai didi

c++ - 是否可以在 C++20 的 requires 子句中初始化模板内部类?

转载 作者:行者123 更新时间:2023-12-05 03:32:45 25 4
gpt4 key购买 nike

考虑以下定义模板内部类 B 的类 A:

struct A {
template<class = int>
struct B { };
};

我们可以使用下面的表达式来初始化内部 B,其中 typename可选的:( Godbolt )

int main() {
A::template B<>();
typename A::template B<>();
}

我想用概念来检测一个类型是否有模板内部类B:

template<class T>
concept C = requires {
typename T::template B<>();
};

static_assert(C<A>);

但只有 Clang 接受了上述代码,GCC 和 MSVC 因语法错误(Godbolt)拒绝了它:

<source>:8:27: error: expected ';' before '(' token
8 | typename T::template B<>();
| ^
| ;

如果我删除 require 子句中的 typename:

template<class T>
concept C = requires {
T::template B<>();
};

MSVC 接受了它,但是 Clang 和 GCC 会生成 static assertion failed 因为它们认为表达式的格式不正确 ( Godbolt ):

<source>:11:15: note: because 'A' does not satisfy 'C'
static_assert(C<A>);
^
<source>:8:15: note: because 'T::template B<>()' would be invalid: 'A::B' instantiated to a class template, not a function template
T::template B<>();
^

我应该信任哪个编译器?

最佳答案

我对概念的理解是,如果你想检查这种情况,你必须使用复合语句。

struct A 
{
template<class = int>
struct B { };
};

template<class T>
concept C = requires
{
{ typename T::template B<>() };
};

static_assert(C<A>);

我相信你不能在 simple requirement 中使用它子句,因为 T::template B<>是从属名称,需要关键字 typename放在前面,因为概念本身是一个模板,而您正处于未评估的环境中。

如果您使用关键字 typename在前面,它不再是simple requirement但变成了 type requirement .但是这个检查类型是否存在,并不是为了构建表达式来实例化类型。

这样你最终会得到一个复合表达式,你可以在其中使用关键字 typename 获取类型在依赖模板中并执行该类型的默认初始化。

作为替代,显示为 C2 , 您可以在概念模板参数列表中预先选择您的类型,这样您就可以在不使用关键字 typename 的情况下使用找到的类型在simple requires clause .

我还添加了测试用例,以通过“杀死”内部类型的默认构造函数来查看概念失败 B .

struct A 
{
template<class = int>
struct B { };
};

struct A2
{
template<class = int>
struct B { B()=delete; };
};


template<class T>
concept C = requires
{
{ typename T::template B<>() };
};


template<class T, typename Inner = typename T::template B<> >
concept C2 = requires
{
Inner();
};


static_assert(C<A>);
static_assert(C<A2>); // fails as expected

static_assert(C2<A>);
static_assert(C2<A2>); // fails as expected

以上代码适用于所有三个给定的编译器:explore

关于c++ - 是否可以在 C++20 的 requires 子句中初始化模板内部类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70411314/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com