2013-03-22 6 views
20

Ten kod nie skompilować na g ++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, z tym błędemoczekuje podstawowej przed wyrazem ">" w g ++, ale nie w programie Microsoft kompilator

test.cpp: In function ‘T mul(V&, V&)’: 
test.cpp:38:27: error: expected primary-expression before ‘>’ token 
test.cpp:38:29: error: expected primary-expression before ‘)’ token 
test.cpp:38:53: error: expected primary-expression before ‘>’ token 
test.cpp:38:55: error: expected primary-expression before ‘)’ token 

ale kompiluje i wykonuje poprawnie Microsoft C/C++ optymalizacja kodu wynikowego Wersja 15.00.21022.08 dla x64

#include <iostream> 
#include <complex> 

template <class T> 
class SM 
{ 
public: 
    T value; 
}; 

template <class T> 
class SC : public SM<T> 
{ 
}; 

class PSSM { 

public: 
    template <class T> 
    T & getSC() { return sc; } 

private: 
    SC<double> sc; 
}; 

class USSM { 

public: 
    template <class T> 
    T & getSC() { return sc; } 

private: 
    SC<std::complex<double> > sc; 
}; 

template <class T, class V> 
T mul(V & G, V & S) { 
    return (G.getSC<SC<T> >().value * S.getSC<SC<T> >().value); // error is here 
} 


int main() { 
    PSSM p; 
    PSSM q; 
    p.getSC<SC<double> >().value = 5; 
    q.getSC<SC<double> >().value = 3; 

    std::cout << mul<double>(p,q); 

} 

nie rozumiem gdzie jest problem. Czy każdy może zrozumieć, jak go obejść lub wyjaśnić naturę problemu w g ++?

Odpowiedz

42

Problem jest składniowy. należy użyć template disambiguator w tym przypadku, tak aby wywołanie szablonu funkcji członek będą prawidłowo przetwarzane:

return (G.template getSC<SC<T> >().value * S.template getSC<SC<T> >().value); 
//  ^^^^^^^^^       ^^^^^^^^^ 

Ten disambiguator pomaga kompilatora uznający, że co następuje G. jest szablon specjalizacji członkiem i nie na przykład element danych o nazwie getSC, a następnie < (mniej niż).

standard odniesienia dla template disambiguator jest Punkt 14,2/4 C++ 11 Standard:

Gdy pojawi się nazwa specjalizacji szablonu człon po . lub -> w przyrostkiem ekspresji lub po zagnieżdżone nazwa-specyfikator w kwalifikowanej ID i ekspresja przedmiotem przyrostkiem ekspresji się zależnie od typu lub zagnieżdżone nazwa-specyfikator w kwalifikowanej ID odnosi się do typu zależnego , ale t nie jest członkiem bieżącej instancji (14.6.2.1), nazwa szablonu elementu członkowskiego musi być poprzedzona prefiksem słowa kluczowego template. W przeciwnym razie przyjmuje się, że nazwa nie jest szablonem. [przykład:

struct X { 
template<std::size_t> X* alloc(); 
template<std::size_t> static X* adjust(); 
}; 
template<class T> void f(T* p) { 
T* p1 = p->alloc<200>(); // ill-formed: < means less than 
T* p2 = p->template alloc<200>(); // OK: < starts template argument list 
T::adjust<100>(); // ill-formed: < means less than 
T::template adjust<100>(); // OK: < starts template argument list 
} 

- przykład koniec]

+0

ale czemu nie jest poprawnie przetwarzane na początku? gdzie powstaje niejednoznaczność? –

+2

Bez słowa kluczowego "szablon", niektóre kompilatory mylą listę parametrów typu z operatorem mniejszym niż. – bstamour

+7

Najbrzydszy. Disambiguator. Zawsze. – mfontanini

Powiązane problemy