views:

400

answers:

2

I know the question is not very descriptive but I couldn't phrase it better.

I'm trying to compile a static linked library that has several objects, all the objects contain the following:

#include foo.h

foo.h is something along these lines:

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

typedef DataT<double> Data;

Now, everything works fine, but if I change DataT to be just Data with double instead of T, I will get a LNK4006 warning at linking time for each .obj stating that the .ctor was already defined.

Edit 1:

#pragma once

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

Edit 2: I'm using MSVC7. The .ctor is actually included in both cases as in

...
public:
   Data(double v);

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

What I'm trying to accomplish though, is not to have that compiled but as a header the user can use.

+1  A: 

If you put the constructor definition in foo.cpp instead of foo.h it will not be compiled separately into every translation unit. At the moment a copy of the constructor is compiled into every object the contains the foo.h include.

The other possible solution would be to the get the compiler to inline the constructor. have you disabled inlining in the compiler settings? The constructor looks easy enough to get automatically inlined.

sth
This seems promising :). I will try it out.
Anzurio
Michael Burr
This is not true with the code posted. It would if the constructor was defined outside of the class definition (outside of the curly braces) but not as it is written.
David Rodríguez - dribeas
+1  A: 

I'm not sure what you're trying to do in the example for edit #2, but I think it might help if you have the following in foo.inl:

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

If the contents of foo.inl is also being included in something where the inline keyword won't work or shouldn't be, you can probably use the preprocessor to handle the difference by using a macro that expands to nothing or inline as appropriate.

Michael Burr
I'm not sure how it will avoid the warning of already-defined.
Anzurio
The 'inline' keyword tells the C++ compiler that it's allowed to be defined multiple times (inline functions are not subject to the "One Definition Rule"). From the standard, "Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in thestandard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8).An inline function shall be defined in every translation unit in which it is used."
Michael Burr
Oh my God, you're a genius, it worked!! thanks!
Anzurio