c++ - 在 C++03 中将指针模板和指向成员函数的指针作为模板参数

标签 c++ templates pointers c++03

我想定义一个带有 2 个模板参数的模板类:

  1. 指针类型 T*
  2. 指向基础类型 T 的成员函数的指针

此外,我想为函数参数设置一个默认方法。

// Do not allow SortedLinkedList<T>
template<typename T, bool (T::* comparisonMethod)(const T&) = &T::lessEqual>
class SortedLinkedList
{
private:
    SortedLinkedList();
};

// Allow SortedLinkedList<T*>
template<typename T, bool (T::* comparisonMethod)(const T&)>
class SortedLinkedList<T*>
{
public:  
    void insert(T* item)
    {
        // do something with /item->*comparisonMethod)(...))
    }
};

此代码无法编译,因为 g++ (4.4.3) 无法推导出 T* 的基础类型

error: creating pointer to member function of non-class type ‘T*’

有没有办法推断类声明中已有的基础类型? decltype 在 C++03 中不可用,我不知道它是否适用于这个地方。

我找到了 this answer ,但在这种情况下没有帮助。

谢谢

最佳答案

问题

编译失败的原因是编译器会检查 primary-template 是一个可行的匹配 before 它继续查看是否有任何特化是更合适的选择。

这意味着当您尝试实例化 SortedLinkedList<A*> , 编译器试图查看声明 bool (T::* comparisonMethod)(const T&) = &T::lessEqual ,在 primary-template 中,格式正确,具有 T = A* - 显然不是(因为指针不能有成员函数)。


解决方案

解决此问题的一种方法是添加一个间接级别,以便主模板和特化都产生格式良好的实例化。

template<class T> struct remove_pointer     { typedef T type; };
template<class T> struct remove_pointer<T*> { typedef T type; };

template<class T>
struct comparison_method_helper {
  typedef typename remove_pointer<T>::type Tx;
  typedef bool (Tx::*type)(Tx const&) const;
};

// primary-template
template<
  class T,
  typename comparison_method_helper<T>::type = &remove_pointer<T>::type::lessEqual
> class SortedLinkedList;

// specialization
template<typename T, typename comparison_method_helper<T>::type func>
class SortedLinkedList<T*, func> {
  public:
    void insert (T const& item) {
      (item.*func) (T ());
    }
};

#include <iostream>

struct A {
  bool lessEqual (A const&) const {
    std::cerr << "hello world\n";
    return false;
  }
};

int main () {
  SortedLinkedList<A*> ().insert (A()); // outputs 'hello world'
}

关于c++ - 在 C++03 中将指针模板和指向成员函数的指针作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28540190/

相关文章:

pointers - 为什么 Go 禁止获取 (&) map 成员的地址,而允许 (&) slice 元素?

c++ - arduino到树莓派串行通信

c++ - 我的 C++ 程序中的段错误

c++ - 如何在 STL map(set) 中查找范围内的所有元素

c++ - 在正确的全局运算符上推导出错误的成员运算符

c++ - 如何为指针和动态内存分配定义模板?

pointers - 如何将对约束字符串的访问传递给 Ada 中的子程序

c++ - 为事件记录系统设计(递归)记录对象

适用于原始数据类型和复杂数据类型的 C++ 模板析构函数

char 双指针混淆行为