【问题标题】:bar(type (&)[x]) definition does not match bar(type (&)[x]) declaration? [duplicate]bar(type (&)[x]) 定义与 bar(type (&)[x]) 声明不匹配? [复制]
【发布时间】:2020-10-29 22:53:55
【问题描述】:

这是Template class type alias failing substitution in member declaration的跟进

考虑这段代码:

// 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 emits the following error:

<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

clang:

<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 似乎有与原始代码和emits the error 类似的问题:

<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 compiles it without complaints

谁对C 是正确的?是 clang 的 bug 还是 gcc 的松懈?

为什么A 不能编译而B 可以?

【问题讨论】:

  • duplicate 情况略有不同,但在阅读了重复答案中链接的文章后,我相信它实际上是同一个问题

标签: c++ templates language-lawyer


【解决方案1】:

正如我在 Template class type alias failing substitution in member declaration 中提到的:

CWG2,这个不知道什么时候发的老问题,还在草拟中,也就是说乱码的匹配规则竟然是未指定。这些奇怪的不匹配是由于编译器的不同实现造成的。

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2019-09-13
    • 1970-01-01
    • 2019-12-10
    相关资源
    最近更新 更多