首页 > 解决方案 > bar(type (&)[x]) 定义与 bar(type (&)[x]) 声明不匹配?

问题描述

这是模板类类型别名在成员声明中替换失败的后续行动

考虑这段代码:

// A
template <typename T>
struct foo {
    using type = unsigned;
   
    template <type x>
    void bar(type (&)[x]);
};
    
template <typename T>
template <typename foo<T>::type x>
void foo<T>::bar(type (&)[x]){}

gcc 发出以下错误:

<source>:13:6: error: no declaration matches 'void foo<T>::bar(foo<T>::type (&)[x])'
   13 | void foo<T>::bar(type (&)[x]){}
      |      ^~~~~~
<source>:8:10: note: candidate is: 'template<class T> template<unsigned int x> void foo<T>::bar(foo<T>::type (&)[x])'
    8 |     void bar(type (&)[x]);
      |          ^~~
<source>:4:8: note: 'struct foo<T>' defined here
    4 | struct foo {
      |        ^~~
Compiler returned: 1

铿锵声

<source>:13:14: error: out-of-line definition of 'bar' does not match any declaration in 'foo<T>'
void foo<T>::bar(type (&)[x]){}
             ^~~
1 error generated.
Compiler returned: 1

当我删除错误定义和候选人中相同的内容时,我得到了这个:

// B
template <typename T>
struct foo {
    using type = unsigned;

    template <type x>
    void bar();
};

template <typename T>
template <typename foo<T>::type x>
void foo<T>::bar(){}

这编译得很好(gcc / clang

试图回答最初的问题(由 Darhuuk,稍作修改)是这样的:

// C
#include <type_traits>

template <typename T> struct length { using type = unsigned int; };    
template <typename T> using length_t = typename length<T>::type;

template <typename type>
class Object {
  template <length_t<Object<type>> length>
  void put(type (&)[length]);
};

template <typename type>
template <length_t<Object<type>> length>
void Object<type>::put(type (&)[length]) {}

int main() {}

Clang 似乎与原始代码有类似的问题并发出错误

<source>:15:20: error: out-of-line definition of 'put' does not match any declaration in 'Object<type>'
void Object<type>::put(type (&)[length]) {}
                   ^~~
1 error generated.

gcc 编译它没有抱怨

谁是对的C?这是clang中的错误还是gcc松懈?

为什么A编译时B不编译?

标签: c++templateslanguage-lawyer

解决方案


正如我 在成员声明中的模板类类型别名失败替换中提到的:

CWG2这个不知道什么时候发的古老的问题还在起草中,这意味着乱码的匹配规则甚至是未指定的。这些奇怪的不匹配是因为编译器的不同实现。


推荐阅读