2014-10-10 61 views
2

这些线路都在不同的头文件,并最终得到包括在下列顺序源文件:如何让这些typedefs工作?

class Alice; 

/* pointers to Alice declared here!! */ 

template<class T> 
class Bob; 

typedef Bob<int> Alice; 

template<class T> 
class Bob 
{ 
}; 

VS2013 error C2371: 'Alice' : redefinition; different basic types

为什么这是一个错误? 任何方法来解决它?

+0

使用不同的名称空间? – ForEveR 2014-10-10 10:23:59

+0

@ForEveR这是一个建议或问题? – 2014-10-10 10:30:28

+0

第一个Alice是一个类,第二个Alice是一个模板。可能这就是它抛出错误的原因。我的问题是为什么你需要这种类型的定义。你可以重命名Alice的任何一个。 – user966379 2014-10-10 10:33:51

回答

3

这是不合适的声明为一个类和一个不同类的typedef。尽管类名和typedef名在许多情况下是可以互换的,但并不总是,例如当类是Aliceclass Alice(使用所谓的详细类型说明符)时,可能指的是类,但如果Alice是typedef名称,则该类型无效。该规则始于C,在那里你只能使用使用详细说明类型说明符,并且必须声明一个单独的typedef才能简单地说出Alice

区别很重要,因为该类型有一个“名称用于链接目的”,它是用于名称绑定的名称,它影响链接器看到的符号。

如果一个文件只看到了typedef名称Alice和使用,对于重整的函数名称,如void foo(Alice*)那么你就不能说功能与其他引用链接到void foo(Bob<int>*)即使它们应该具有相同的重整名称。

因此,编译器必须区分类型定义(它们只是别名)和类型的“真实名称”(即它的名称用于链接目的)。

唯一的解决方法是正确声明的类型,这样的Alice作为一个typedef声明使用无处不在,即以取代不真实class Alice;声明:

template<class T> class Bob; 
typedef Bob<int> Alice; 
+0

嗨,谢谢。有没有解决办法? – 2014-10-10 10:35:38

+0

template class Bob {}; typedef Bob Alice; – Clearer 2014-10-10 10:40:04

+1

@Clearer,你不需要定义'Bob'为了能够声明'Alice' typedef,你只需要声明它。 – 2014-10-10 10:41:10

1

您可以使用继承作为一个可能的解决方法:

class Alice; 

Alice* a1; 

template<typename T> 
class Bob {}; 

class Alice : public Bob<int> {} ; 
0

如果我认为这是正确的,有说法

Alice obj; 

编译器如何解释“Alice”。在符号表中会有2个条目:一个作为一个类,另一个作为模板。

这就是为什么它给错误。