bar(type(&)[x])定义与bar(type(&)[x])声明不匹配? [英] bar(type (&)[x]) definition does not match bar(type (&)[x]) declaration?

查看:83
本文介绍了bar(type(&)[x])定义与bar(type(&)[x])声明不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是模板类类型别名未能在成员声明中替换的后续操作

考虑以下代码:

 //A模板< typename T>struct foo {使用type = unsigned;模板< type x>空格(类型(&)[x]);};模板< typename T>模板< typename foo< T> :: type x>void foo< T> :: bar(type(&)[x]){} 

gcc发出以下错误:

 < source>:13:6:错误:没有声明与'void foo< T> :: bar(foo< T> :: type(&)[x])'相匹配13 |void foo< T> :: bar(type(&)[x]){}|^ ~~~~~< source>:8:10:注意:候选者是:'template< class T>template< unsigned int x>void foo< T> :: bar(foo< T> :: type(&)[x])'8 |空格(类型(&)[x]);|^ ~~< source>:4:8:注意:'struct foo< T>'在这里定义4 |struct foo {|^ ~~编译器返回:1 

c语:

 < source>:13:14:错误:"bar"的脱机定义与"foo< T>"中的任何声明都不匹配void foo< T> :: bar(type(&)[x]){}^ ~~产生1个错误.编译器返回:1 

当我删除错误定义中与候选对象相同的内容时,我会得到以下提示:

 //B模板< typename T>struct foo {使用type = unsigned;模板< type x>无效bar();};模板< typename T>模板< typename foo< T> :: type x>无效foo< T> :: bar(){} 

这可以很好地进行编译( gcc /出现错误:

 < source>:15:20:错误:"put"的离线定义与"Object< type>"中的任何声明都不匹配void Object< type> :: put(type(&)[length]){}^ ~~产生1个错误. 

gcc对其进行编译而没有任何投诉.

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

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

正如我在 CWG2 ,这是一个没人知道何时发布的古老问题,仍然是草稿,这意味着超出范围的匹配规则甚至是未指定.这些奇怪的不匹配是由于编译器的实现方式不同.

This is a follow up of Template class type alias failing substitution in member declaration

Consider this code:

// 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

When I remove what is identical in the erroneous definition and the candidate I get this:

// 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(){}

This compiles fine (gcc / clang)

An attempt to answer the original question (by Darhuuk, slightly modified) was this:

// 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 seems to have similar problems as with the original code and 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.

while gcc compiles it without complaints.

Who is right about C? Is it a bug in clang or is gcc being lax?

Why does A not compile while B does?

解决方案

as I mentioned in Template class type alias failing substitution in member declaration:

CWG2, the ancient issue that nobody knows when it's posted, is still drafting, which means the match rule of out-of-definition is even unspecified. these weird mismatches are because of the different implementations of compilers.

这篇关于bar(type(&amp;)[x])定义与bar(type(&amp;)[x])声明不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆