首页 文章

具有指针模板和指向成员函数的指针作为C 03中的模板参数

提问于
浏览
2

我想用2个模板参数定义一个模板类:

  • 指针类型T *

  • 指向基础类型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,但在这种情况下没有帮助 .

谢谢

1 回答

  • 1

    问题

    它无法编译的原因是编译器将检查主模板是否可行匹配 before 继续查看是否有任何特殊化是更合适的替代方案 .

    这意味着当您尝试实例化 SortedLinkedList<A*> 时,编译器会尝试查看主模板中的声明 bool (T::* comparisonMethod)(const T&) = &T::lessEqual 是否具有 T = A* 的格式良好 - 显然它不具有成员函数't (since pointers can' .


    解决方案

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

    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'
    }
    

相关问题