这个问题很难在没有例子的情况下提出,所以这里是:
#include <vector>
struct O
{
};
struct C
{
template <typename T>
void function1(void (C::*callback)(const O*));
template <typename T>
void function2(void (C::*callback)(const typename T::value_type));
void print(const O*);
};
int main()
{
C c;
c.function1< std::vector<O*> >(&C::print); // Success.
c.function2< std::vector<O*> >(&C::print); // Fail.
}
我得到的错误是:
error: no matching function for call to ‘C::function2(void (C::*)(const O*))’
。
基本上,调用之间的唯一区别是在function2
中,我更通用,因为我使用的typedef std::vector<O*>::value_type
应该解析为O*
,因此类似于{{1 }}
我正在使用G ++ 4.2.1(我知道它已经老了),但是Comeau确认我错了。
为什么编译失败?
答案 0 :(得分:4)
您的问题是,const typename T::value_type
基本上typename T::value_type const
解析为O* const
,这显然与const O*
(O const *
不同,在类型后面写ptr声明(更有用于弄清楚这种行为))。
至于归档你想要的东西,这取决于你想要什么。如果你想要,你可以使用boost type_traits
或tr1 type_traits
去除指针,添加const并再次使它成为指针:
template <typename T>
void function2(void (C::*callback)(typename boost::add_pointer<typename boost::add_const<typename boost::remove_pointer<typename T::value_type>::type>::type>::type));
使用tr1
代替boost
基本上应该将boost::
替换为std::tr1::
。
但是我并不认为这是一个有用的概括,所以如果你真的想要这样做,你可能想要过度思考。就个人而言,我要么使用像boost function
这样的东西,要么使用自由函数作为回调,前者允许在可用作回调(自由函数,仿函数,成员函数)的内容方面具有更大的灵活性,而后者至少可以使它变得简单创建第二个函数,它将适当地转换参数(即如果你想使用一个获得const O*
作为参数的函数,你可以创建一个取O*
并用该参数调用第一个函数的函数并使用那个作为回调)。