" の前に primary-expression が必要ですが、Microsoft コンパイラではそうではありません 質問する">
このコードはg++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3ではコンパイルに失敗し、次のエラーが発生します。
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用のMicrosoft C/C++最適化コンパイラバージョン15.00.21022.08では正しくコンパイルおよび実行されます。
#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);
}
どこに問題があるのか分かりません。回避策を理解できる方、または g++ における問題の本質を説明できる方はいらっしゃいますか?
ベストアンサー1
問題は構文上のものです。template
この場合は、メンバー関数テンプレートの呼び出しが正しく解析されるように、曖昧さ回避を使用する必要があります。
return (G.template getSC<SC<T> >().value * S.template getSC<SC<T> >().value);
// ^^^^^^^^^ ^^^^^^^^^
この曖昧さ回避機能は、コンパイラが次に続くのG.
がメンバーテンプレートの特殊化たとえば、データ メンバーgetSC
の後に<
(より小さい) が続くようなことはありません。
曖昧さ回避の標準リファレンスtemplate
は、C++11 標準のパラグラフ 14.2/4 です。
メンバーテンプレートの特殊化の名前が後置式の後
.
または後置式の後に現れる場合、または->
ネストされた名前指定子で修飾ID、およびオブジェクトの表現接尾辞表現タイプ依存か、ネストされた名前指定子修飾IDは依存型を参照しているが、名前は現在のインスタンス化のメンバーではない(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 }
—例の終了]