2009-08-06 43 views
1

我知道这个问题不是非常具有描述性,但我不能更好地描述它。如何在不使用模板时摆脱警告LNK4006?

我试图编译有几个对象的静态链接库,所有的对象包含以下内容:

#include foo.h 

了foo.h是沿着这些路线的东西:

#pragma once 
template<class T> 
class DataT{ 
    private: 
     T m_v; 
    public: 
     DataT(T v) : m_v(v){} 
}; 

typedef DataT<double> Data; 

现在,一切工作正常,但如果我改变DataT只是双数据而不是T,我会得到一个LNK4006警告链接时间为每个.obj声明.ctor已被定义。

编辑1:

#pragma once 

class Data{ 
    private: 
     double m_v; 
    public: 
     Data(double v) : m_v(v){} 
}; 

编辑2: 我使用MSVC7。 的.ctor实际上是包含在这两种情况下,如

... 
public: 
    Data(double v); 

#include foo.inl 
... 
//foo.inl 
Data::Data(double v): m_v(v) {} 

什么我想虽然完成,是不是有编制,但作为一个头中的用户可以使用。

+2

你可以显示更改后的代码的样子吗? – gatorfax 2009-08-06 18:46:25

+0

你使用了什么确切的编译器?代码是否真的像你发布的那样? (特别是,在类体中定义的构造函数?还是定义了类定义的外部?这是特别重要的)。正如Mike所评论的那样:如果您在某些特定代码方面存在问题,请向您提供问题的代码,而不是其他一些编译完好的代码。我的猜测是你在.h里面定义了构造函数,但是在类之外。 – 2009-08-06 19:15:39

+0

现在你可以展示如何使用头和数据类了吗?显示的标题工作正常。所有的.cpp文件都被重新编译了吗? – 2009-08-06 19:16:47

回答

2

我不知道你想在编辑#2的例子做什么,但我想如果你有foo.inl下面可能会有所帮助:

inline 
Data::Data(double v): m_v(v) {} 

如果foo.inl的内容也包含在inline关键字不起作用或不应该出现的地方,您可以使用预处理器来处理差异,方法是使用一个扩展为无效的宏或适当的inline

+0

我不确定它将如何避免已定义的警告。 – Anzurio 2009-08-06 21:45:56

+0

'inline'关键字告诉C++编译器它允许多次定义(内联函数不受“One Definition Rule”限制)。从标准中,“每个程序应该包含该程序中使用的每个非内联函数或对象的一个​​定义;不需要诊断。定义可以在程序中显式出现,可以在 标准中找到,或者用户自定义库,或者(如果适用)它是隐式定义的(见12.1,12.4和12.8)。 内联函数应在使用它的每个翻译单元中定义。 – 2009-08-06 23:26:36

+0

哦,我的天啊,你是天才,它工作!谢谢! – Anzurio 2009-08-07 00:52:43

1

如果将构造函数的定义写入foo.cpp而不是foo.h,则不会将其分别编译到每个翻译单元中。此刻构造函数的副本被编译到包含foo.h包含的每个对象中。

另一种可能的解决方案是让编译器内联构造函数。你有没有在编译器设置中禁用内联?构造函数看起来非常简单,可以自动内联。

+0

这似乎很有前途:)。我会试试看。 – Anzurio 2009-08-06 18:49:46

+1

但是这不应该是一个问题,因为定义是内联的,这在C++中是允许的(并且必须由编译器和工具支持) – 2009-08-06 19:08:46

+0

这不适用于发布的代码。如果构造函数是在类定义之外(大括号外)定义的,但不是写成的。 – 2009-08-06 19:10:07