2009-08-06 6 views
1

Ich weiß, dass die Frage nicht sehr beschreibend ist, aber ich könnte es nicht besser ausdrücken.Wie kann man die Warnung LNK4006 loswerden, wenn keine Vorlagen verwendet werden?

Ich versuche, eine statische verknüpfte Bibliothek zu kompilieren, die mehrere Objekte enthält, werden alle Objekte enthalten die folgenden:

#include foo.h 

foo.h ist etwas in dieser Richtung:

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

typedef DataT<double> Data; 

Jetzt , alles funktioniert gut, aber wenn ich DataT so ändere, dass es nur Data mit double statt T ist, erhalte ich eine LNK4006-Warnung bei der Verbindungszeit für jede .obj, die besagt, dass die .ctor bereits definiert wurde.

Edit 1:

#pragma once 

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

Edit 2: ich MSVC7 bin mit. Die .ctor tatsächlich in beiden Fällen wie in

... 
public: 
    Data(double v); 

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

enthalten ist, Was ich versuche aber, zu erreichen, ist nicht so zusammengestellt zu haben, aber als Header kann der Benutzer verwenden.

+2

Können Sie zeigen, wie der geänderte Code aussieht? – gatorfax

+0

Welchen genauen Compiler benutzen Sie? Ist der Code wirklich so, wie du ihn postest? (Ist der Konstruktor insbesondere im Klassenkörper definiert oder ist er außerhalb der Klassendefinition definiert? Dies ist besonders wichtig). Wie Mike kommentierte: Wenn Sie Probleme mit einem bestimmten Code haben, schreiben Sie den Code, der Ihnen Probleme bereitet, nicht irgendeinen anderen Code, der perfekt kompiliert. Meine Vermutung ist, dass Sie den Konstruktor innerhalb der .h aber außerhalb der Klasse definieren. –

+0

Jetzt können Sie zeigen, wie der Header und die Data-Klasse verwendet werden? Der angezeigte Header funktioniert einwandfrei. Werden alle CPP-Dateien neu kompiliert? –

Antwort

2

Ich bin nicht sicher, was Sie versuchen zu bearbeiten # 2 in dem Beispiel zu tun, aber ich denke, es könnte helfen, wenn Sie das folgende in foo.inl haben:

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

Wenn Der Inhalt von foo.inl wird auch in etwas enthalten, wo das Schlüsselwort inline nicht funktioniert oder nicht sein sollte. Sie können wahrscheinlich den Präprozessor verwenden, um den Unterschied zu behandeln, indem Sie ein Makro verwenden, das zu nichts erweitert oder inline.

+0

Ich bin nicht sicher, wie es die Warnung von bereits definiert vermeiden wird. – Anzurio

+0

Das Schlüsselwort 'inline' teilt dem C++ - Compiler mit, dass es mehrfach definiert werden darf (Inline-Funktionen unterliegen nicht der "One Definition Rule"). Aus dem Standard: "Jedes Programm muss genau eine Definition jeder nichtlinearen Funktion oder eines Objekts enthalten, das in diesem Programm verwendet wird; keine Diagnose erforderlich. Die Definition kann explizit im Programm erscheinen, sie kann im Standard oder a Benutzerdefinierte Bibliothek oder (falls zutreffend) implizit definiert (siehe 12.1, 12.4 und 12.8) Eine Inline-Funktion muss in jeder Übersetzungseinheit definiert werden, in der sie verwendet wird. " –

+0

Oh mein Gott, du bist ein Genie, es hat funktioniert !! Vielen Dank! – Anzurio

1

Wenn Sie die Konstruktordefinition in foo.cpp anstelle von foo.h setzen, wird sie nicht in jede Übersetzungseinheit separat kompiliert. Im Moment wird eine Kopie des Konstruktors in jedes Objekt kompiliert, das die foo.h Include enthält.

Die andere mögliche Lösung wäre, den Compiler zum Inline-Konstruktor zu bringen. Hast du das Inlining in den Compiler-Einstellungen deaktiviert? Der Konstruktor sieht so einfach aus, dass er automatisch inline wird.

+0

Das scheint vielversprechend :). Ich werde es ausprobieren. – Anzurio

+1

Aber das sollte kein Problem sein, da die Definition inline ist, was in C++ erlaubt ist (und muss vom Compiler & Tools unterstützt werden) –

+0

Dies ist nicht wahr mit dem Code geschrieben. Es wäre, wenn der Konstruktor außerhalb der Klassendefinition (außerhalb der geschweiften Klammern) definiert wäre, aber nicht so, wie er geschrieben wurde. –

Verwandte Themen