如何从成员函数模板类型签名中删除const?

时间:2011-03-25 15:25:29

标签: c++ templates visual-c++ g++ metaprogramming

我正在研究一些C ++类型系统的东西,并且我在从成员函数中删除const-ness以与函数特征类一起使用时遇到问题。真正令人难以置信的是,这对G ++运行良好,但是MSVC10无法正确处理部分特化,我不知道其中一个编译器是否真的有错误。

这里的问题是,从成员函数中删除const限定符的正确方法是什么,以便我可以获得函数类型签名?

采用以下代码示例:

  #include <iostream>

  template<typename T> struct RemovePointer { typedef T Type; };
  template<typename T> struct RemovePointer<T*> { typedef T Type; };
  template<typename R,typename T> struct RemovePointer<R (T::*)> { typedef R Type; };

  class A {
  public:
     static int StaticMember() { return 0; }
     int Member() { return 0; }
     int ConstMember() const { return 0; }
  };

  template<typename T> void PrintType(T arg) {
     std::cout << typeid(typename RemovePointer<T>::Type).name() << std::endl;
  }

  int main()
  {
     PrintType(&A::StaticMember);
     PrintType(&A::Member);
     PrintType(&A::ConstMember); // WTF?
  }

所有这三个PrintType语句都应该打印相同的东西。 MSVC10打印以下内容:

int __cdecl(void)
int __cdecl(void)
int (__cdecl A::*)(void)const __ptr64

g ++打印这个(这是预期的结果):

FivE
FivE
FivE

3 个答案:

答案 0 :(得分:3)

我建议你看看Alexandrescu的loki图书馆的TypeTraits.h。 它提供了一种剥离限定符的通用方法,例如const。

http://loki-lib.cvs.sourceforge.net/loki-lib/loki/include/loki/TypeTraits.h?view=markup

当我对元编程c ++元编程有一些哲学问题时,如果对我的行踪有答案,我倾向于使用现代c ++设计。

答案 1 :(得分:1)

这个会有所帮助:

template<typename R,typename T> struct RemovePointer<R (T::*)() const> { typedef R Type; };

请注意,您可能也希望在前一行中添加()(否则它将匹配指向成员的指针和指向函数的指针):

template<typename R,typename T> struct RemovePointer<R (T::*)()> { typedef R Type; };

答案 2 :(得分:1)

typeid(...).name()返回实现定义的字符串。它可能是编译器错位的符号,也可能是Jon Skeet编写的一首诗。请不要依赖它来做任何有用的事情。

想要取消“const”似乎也很奇怪;函数 const,那么为什么你不想在结果字符串中使用它呢?

我不知道你为什么期待或看到“FIvE”。我在你的代码中看不到类似的东西。

相关问题