如何从成员函数模板类型签名中删除常量? 我正在研究一些C++类型的系统,我在从成员函数中删除常量,用函数特性类来解决问题。这里真正鼓吹的是,这在G++中可以正常工作,但MSVC10无法正确处理部分专门化,我不知道这些编译器中是否有一个在这里有bug

如何从成员函数模板类型签名中删除常量? 我正在研究一些C++类型的系统,我在从成员函数中删除常量,用函数特性类来解决问题。这里真正鼓吹的是,这在G++中可以正常工作,但MSVC10无法正确处理部分专门化,我不知道这些编译器中是否有一个在这里有bug,c++,templates,visual-c++,g++,metaprogramming,C++,Templates,Visual C++,G++,Metaprogramming,这里的问题是,从成员函数中删除const限定符的正确方法是什么,这样我就可以获得函数类型签名 以以下代码示例为例: #include <iostream> template<typename T> struct RemovePointer { typedef T Type; }; template<typename T> struct RemovePointer<T*> { typedef T Type; }; template&

这里的问题是,从成员函数中删除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?
  }
g++打印此内容(这是预期结果):

这将有助于:

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

我建议你看看Alexandrescu的loki库的TypeTraits.h。 它提供了一种去除限定符的通用方法,如const

当我在元编程C++编程中遇到一些哲学问题时,如果我的下落有答案,我倾向于使用现代C++设计。p>
typeid(…).name()
返回实现定义的字符串。它可能是一个被编译器弄坏的符号,也可能是乔恩·斯基特写的一首诗。请不要依赖它来做任何有用的事情

想要去掉“const”似乎也很奇怪;函数是
const
,那么为什么不希望在结果字符串中使用它呢


我不知道你为什么期待或看到“五”。我在您的代码中看不到类似的内容。

“从成员函数中删除常量限定符的正确方法是什么,这样我就可以获得函数类型签名?”成员函数的常量限定符是其签名的一部分。我不知道您想要它做什么,但是静态成员函数和非静态成员函数的签名是不同的。我发现前两行的输出相等,比第三行不同更糟糕。您真正想要解决的是什么?typeid中的name()完全是特定于实现的。你怎么能说出哪一个是对的还是错的?@BoPersson你没有抓住重点。GCC打印的类型是错误的(基于
c++filt
的Demanling)。第三个应该是
int()常量
,但它说它是
int()
。这实际上不起作用。这会导致R匹配返回类型,而不是函数类型。我明白了。。。然后我怀疑它是否应该是可编译的:为什么
R(T::*)
中的
R
应该是“函数类型”?我不确定这个语法是怎么回事(我从来没有使用指向成员函数的指针),但这是有效的。有趣的是,我确信
R(T const::*)
应该可以工作(因为它是
T
类型,应该是
const
),但这不起作用…@Konrad如果类中有
void f()const{}
,那么这就定义了一个类型为
void()const
的成员。因此,如果您获取类C的成员指针,您将得到一个
void(C:::*)()常量
,或者用另一种方式表示,
rc:*
,其中
R
void()常量
。这与说
R
U常量不同,其中
U
void()
:没有常量函数类型。函数类型末尾的常量不会使函数成为“不可修改”之类的函数。这与
R
void()
C
const U
的方式也不同。您拥有的是类
C
的成员指针。不是类类型
常量U
。成员具有特定类型,而不是类。这解决了我的问题。这不是我想要的方式,但它表明我不能用几行代码来完成我所需要的。谢谢<代码>五
是一种破损类型。使用GNU demangler,
c++FiltFive
给出
int()()
FivE
FivE
FivE
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; };