2016-04-26 8 views
0

Ich benutze manchmal die ehemalige als Testbed und dann Code zu meinem realen Projekt in XCode bewegen. Das funktioniert in diesem Fall nicht für mich. Der folgende Code kompiliert und läuft auf Coliru (siehe cat /Archive2/48/70c3935989bffb/main.cpp), aber nicht auf XCode.Warum kompiliert dieser Code auf Coliru, aber nicht auf Xcode?

#include <cassert> 

template <typename T, typename P> 
class Permutation 
{ 
public: 

    virtual bool operator==(const P& other) const; 
    // other member functions not listed here use the type T 
}; 

template <typename T> 
class SmallPermutation : public Permutation<T, SmallPermutation<T> > 
{  
public: 

    SmallPermutation(int i);  
    virtual bool operator==(const SmallPermutation& other) const; 
    int code; 
    // other member functions not listed here use the type T 
}; 


template <typename T> 
SmallPermutation<T>::SmallPermutation(int i) 
{ 
    code = i; 
} 

template <typename T> 
bool SmallPermutation<T>::operator==(const SmallPermutation& other) const 
{ 
    return code == other.code; 
} 

int main() 
{  
    SmallPermutation<int> a(4); 
    SmallPermutation<int> b(7); 
    SmallPermutation<int> c(4); 

    assert(a == c); 
    assert(!(a == b)); 

    return 0; 
} 

Hier ist ein Teil der Fehlermeldung von XCode (die ich nicht verstehe):

Undefined symbols for architecture x86_64: 
"Permutation<int, SmallPermutation<int> >::operator==(SmallPermutation<int> const&) const", referenced from: 
    vtable for Permutation<int, SmallPermutation<int> > in permutationTest.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

Gibt es etwas Nicht-Standard über den Code? Gibt es Build/Compile/Environment-Einstellungen in XCode, die ich anpassen muss?

Hintergrund: Ich habe mehrere (Vorlage) Klassen mit der gleichen Schnittstelle und möchte, dass sie alle von einer abstrakten Klasse erben. Das Template-Zeug macht diese Aufgabe etwas schwieriger. Ich habe (möglicherweise fälschlicherweise) eine Technik namens CRTP (Curiously Recurring Template Pattern) verwendet, um das zu ermöglichen.

Antwort

1

Wenn Sie eine nicht-reine virtuelle Funktion deklarieren, wie die operator== Funktion in Ihrer Permutation Klasse, dann muss es eine Definition haben, Sie müssen einen Funktionskörper für die Funktion bereitstellen.

Die Lösung ist entweder rein zu machen:

virtual bool operator==(const P& other) const = 0; 

Oder eine Dummy-Implementierung zur Verfügung zu stellen:

virtual bool operator==(const P& other) const { return false; } 
+0

Diese einfache Anpassung meines Build behoben! Ich frage mich immer noch, warum der Unterschied im Verhalten in den beiden Frameworks ist. – sitiposit

Verwandte Themen