存储成员函数模板实例时出错
Error storing instance of member function template
我正在尝试存储指向成员函数模板 Derived::initialize
实例的指针,如下所示(另请参阅问题的 rextester.com. For posterity, I've created a simpler version。):
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 setterImpl<0>
有效,而 C::template SetterInterface<0>::Function
(我认为它是前者的别名)无效。例如:
Base::setterFunction f1 = &Base::setterImpl<0>;
Base::setterFunction f2 = Base::template SetterInterface<0>::Function;
问题是initialize()
非类型模板参数应该是常量表达式;在你的代码中它是一个静态成员,所以它不能工作;它可以,如果你将它声明为 static 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>;
};
};
我正在尝试存储指向成员函数模板 Derived::initialize
实例的指针,如下所示(另请参阅问题的 rextester.com. For posterity, I've created a simpler version。):
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 setterImpl<0>
有效,而 C::template SetterInterface<0>::Function
(我认为它是前者的别名)无效。例如:
Base::setterFunction f1 = &Base::setterImpl<0>;
Base::setterFunction f2 = Base::template SetterInterface<0>::Function;
问题是initialize()
非类型模板参数应该是常量表达式;在你的代码中它是一个静态成员,所以它不能工作;它可以,如果你将它声明为 static 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>;
};
};