【问题标题】:out of line definition of guided constructor (c++20)引导构造函数的异常定义(c ++ 20)
【发布时间】:2021-04-01 12:53:17
【问题描述】:

g++ 很乐意接受以下代码,而 clang 和 msvc 都能够匹配行外定义。

知道为什么吗?

template <bool B>
struct test 
{
    test() requires (B);
    test() requires(!B);
};


template <>
test<true>::test()
{}

template <>
test<false>::test()
{}

int main()
{
    test<false> a;
    test<true> b;
    return 0;
}

Demo

叮当声:

错误:“test”的行外定义与“test&lt;true&gt;”中的任何声明都不匹配

Msvc:

错误 C2244:'test&lt;true&gt;::test':无法将函数定义与现有声明匹配

【问题讨论】:

  • 我很想说你不需要约束,因为无论如何你都在专门化构造函数。

标签: c++ constructor require c++20


【解决方案1】:

您声明了受约束的构造函数,但定义了两个不受约束的特化。这些永远不会匹配。

你的意思可能是:

template <bool B>
struct test
{
    test() requires (B);
    test() requires(!B);
};

template <bool B>
test<B>::test() requires (B)
{}

template <bool B>
test<B>::test() requires (!B)
{}

这在所有 3 个编译器中都能正常编译。

至于为什么您的原始版本可以编译 - 这是一个 GCC 错误96830。 Clang 是对的,代码格式不正确,因为行外定义与模板定义不匹配(还要注意 template&lt;&gt; ...完全专业化 语法)。

[temp.class.general]/3(强调我的):

当类模板的成员在类模板定义之外定义时,该成员定义被定义为具有template-head 等效的模板定义> 到类模板的那个。

[temp.over.link]/6:

如果两个 template-headstemplate-parameter-lists 长度相同,则 等价,对应template-parameters 是等价的,并且都用 type-constraints 声明,如果 template-parametertype 声明,则它们是等价的-constraint如果任何一个template-head有requires-clause,它们都有requires-clauses并且对应的constraint-expression是等价的 .

另请参阅[temp.mem.func]/1 以获取声明受约束成员的示例:

template<typename T> struct S {
    void f() requires C<T>;
    void g() requires C<T>;
};

template<typename T>
void S<T>::f() requires C<T> { }      // OK
template<typename T>
void S<T>::g() { }                    // error: no matching function in S<T>

【讨论】:

  • 如何专精?添加requires(true) 也不起作用Demo
  • @Jarod42 根据this 它应该编译。那么也许两个编译器都不支持它?
  • 非常感谢您的回答。完整的专业化不起作用,并且很难找到有关该主题的文档。完全专业化(无需要求)可能与 gcc 一起使用,因为最终(损坏的)符号匹配......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多