web-dev-qa-db-ja.com

テンプレート基本クラスのテンプレート関数を呼び出す

重複の可能性:
「template」および「typename」キーワードをどこに、なぜ配置する必要があるのですか?

コードは次のとおりです。

_template<typename T>
class base
{
public:
    virtual ~base();

    template<typename F>
    void foo()
    {
        std::cout << "base::foo<F>()" << std::endl;
    }
};

template<typename T>
class derived : public base<T>
{
public:
    void bar()
    {
        this->foo<int>(); // Compile error
    } 
};
_

そして、実行中:

_derived<bool> d;
d.bar();
_

次のエラーが発生します。

_error: expected primary-expression before ‘int’
error: expected ‘;’ before ‘int’
_

私は知っています 非依存名と2フェーズルックアップ 。しかし、関数自体がテンプレート関数(私のコードではfoo<>()関数)である場合、すべての回避策を試しましたが失敗しました。

16
Daniel K.

fooは従属名であるため、typenameまたはtemplateキーワードを使用して別の方法で指定しない限り、第1フェーズのルックアップでは変数であると見なされます。この場合、次のことが必要です。

this->template foo<int>();

すべての厄介な詳細が必要な場合は、 この質問 を参照してください。

29
Mike Seymour

あなたはこのようにそれをするべきです:

template<typename T>
class derived : public base<T>
{
public:
    void bar()
    {
        base<T>::template foo<int>();
    } 
};

これが完全にコンパイル可能な例です:

#include <iostream>

template<typename T>
class base
{
public:
    virtual ~base(){}

    template<typename F>
    void foo()
    {
        std::cout << "base::foo<F>()" << std::endl;
    }
};

template<typename T>
class derived : public base<T>
{
public:

    void bar()
    {
        base<T>::template foo<int>(); // Compile error
    }
};

int main()
{
  derived< int > a;
  a.bar();
}
11
BЈовић