函数参数中的Typedef等价

时间:2011-01-17 22:49:23

标签: c++ templates gcc typedef

这个问题很难在没有例子的情况下提出,所以这里是:

#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确认我错了。

为什么编译失败?

1 个答案:

答案 0 :(得分:4)

您的问题是,const typename T::value_type基本上typename T::value_type const解析为O* const,这显然与const O*O const *不同,在类型后面写ptr声明(更有用于弄清楚这种行为))。

至于归档你想要的东西,这取决于你想要什么。如果你想要,你可以使用boost type_traitstr1 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*并用该参数调用第一个函数的函数并使用那个作为回调)。