2013-03-22 8 views
20
このコードは、グラムでコンパイルに失敗

++ 4.6.3(4.6.3-1ubuntu5 /リナロUbuntuの)、期待プライマリー・表現「>」G ++の前ではなく、マイクロソフトのコンパイラでこのエラーと

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 

が、それはコンパイルおよび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); 

} 

問題がどこにあるか私は理解していないために、Microsoft C/C++最適化コンパイラバージョン15.00.21022.08で正しく実行されます。誰かがそれを回避する方法を理解することができますか、またはg ++の問題の性質を説明できますか?

答えて

42

問題は構文的です。メンバ関数テンプレートのあなたの呼び出しが正しく解析されるようにあなたは、このケースではtemplateディスアンビギュエータを使用する必要があります。

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

このディスアンビギュエータは何G.を次のことメンバーテンプレートの特殊ではないことを認識し、コンパイラを支援しますたとえば、getSCというデータメンバーと、それに続く<というデータメンバーがあります。

templateディスアンビギュエータのための標準的な基準は、C++ 11標準のパラグラフ14.2/4:

メンバテンプレート特殊化の名前が表示された後置発現または後.または->修飾-ID、及びPostfixの発現のオブジェクト表現でネスト名指定子修飾-IDを入力依存性またはネスト名指定子依存タイプを指しますしかし、t彼は現在のインスタンシエーション(14.6.2.1)のメンバーではありません。メンバテンプレート名の先頭にキーワードtemplateを付ける必要があります。それ以外の場合、名前はテンプレートではないと見なされます。 [例:

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 
} 

からエンド例]

+0

が、なぜそれが正しくで始めるために解析されていませんか?あいまいさはどこで発生しますか? –

+2

'template'キーワードがないと、コンパイラによって型パラメータのリストと小なり演算子が混同されることがあります。 – bstamour

+7

最も醜い。曖昧さ回避これまで – mfontanini

関連する問題