2017-11-20 2 views
4

メンバ関数テンプレートDerived::initializeのインスタンスへのポインタを格納しようとしています(rextester.comも参照してください)。メンバ関数テンプレートのインスタンスを格納する際にエラーが発生しました

class Base 
{ 
public: 
    typedef void (Base::*setterFunction)(unsigned); 

    template<unsigned N> 
    struct SetterInterface 
    { 
     static Base::setterFunction Function; 
    }; 

protected: 
    template<unsigned N> 
    void setterImpl(unsigned) 
    { 
    } 
}; 

template<unsigned N> 
Base::setterFunction Base::SetterInterface<N>::Function = &Base::setterImpl<N>; 

class Derived : public Base 
{ 
public: 
    typedef void (Derived::*Initializer)(); 

    template<typename T , void (T::*F)(unsigned) > 
    void initialize() 
    { 
    } 

    template<typename C> 
    Derived(C*) 
    { 
     Initializer initializer = &Derived::initialize<C, C::template SetterInterface<0>::Function>; // NOT OK 
     //Initializer initializer = &Derived::initialize<C, C::template setterImpl<0> >; // OK 
    } 
}; 

int main() 
{ 
    Derived derived((Base*)0); 
} 

しかし、私はGCC 5.4.0(および6.4.0)にエラーメッセージが出てい

Test.cpp: In instantiation of ‘Derived::Derived(C*) [with C = Base]’: 
Test.cpp:45:28: required from here 
Test.cpp:37:39: error: no matches converting function ‘initialize’ to type ‘Derived::Initializer {aka void (class Derived::*)()}’ 
    Initializer initializer = &Derived::initialize<C, C::template SetterInterface<0>::Function>; 
            ^
Test.cpp:30:7: note: candidate is: template<class T, void (T::* F1)(unsigned int)> void Derived::initialize() 
    void initialize() 

問題はメンバ関数テンプレート引数であるように見えるので、C::template SetterInterface<0>::Functionに対しC::template setterImpl<0>作品(WH私は前者のエイリアスと思われる)はそうではありません。例えば:

Base::setterFunction f1 = &Base::setterImpl<0>; 
Base::setterFunction f2 = Base::template SetterInterface<0>::Function; 
+2

のinitialize()非型テンプレートパラメータは定数式でなければなりません。あなたのコードでは代わりに静的メンバーなので、うまく動作しません。静的なconstexprとして宣言していれば可能です。とにかく、あなたは何を達成しようとしていますか? –

答えて

3

問題がinitialize()非型テンプレートパラメータは定数式でなければならないということです。あなたのコードでは代わりに静的メンバーなので、うまく動作しません。それはあなたが静的constexprのとしてそれを宣言した(ただし、その後、少なくともC++ 11コンパイラを必要があるだろう)場合は、可能性:

class Base 
{ 
protected: 
    template<unsigned N> 
    void setterImpl(unsigned); 
public: 
    typedef void (Base::*setterFunction)(unsigned); 

    template<unsigned N> 
    struct SetterInterface 
    { 
     static constexpr Base::setterFunction Function = &Base::setterImpl<N>; 
    }; 
}; 
+0

残念ながら私はC++ 98/03に制限されています。これを示すために質問タグを改訂しています。 – Olumide

+0

@olumideそのままですが、あなたが望むものはC++ではできないようです03;あなたはsetterImplを直接渡すのはなぜですか? –

+0

'setterImpl'は、' Derived'が継承する他の基本クラス(図示せず)に別の名前があるので、できません。したがって、 'SetterInterface :: Function'はこれらのメンバ関数の総称名を作成しようとします。 – Olumide

関連する問題