24

このコードは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

ただし、Microsoft C / C ++OptimizingCompilerバージョン15.00.21022.08forx64では正しくコンパイルおよび実行されます。

#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 ++の問題の性質を説明したりできますか?

4

1 に答える 1

52

問題は構文です。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
}

—<em>例を終了]

于 2013-03-22T14:12:03.347 に答える