如何将运算符作为默认仿函数参数传递?

时间:2011-11-02 05:52:28

标签: c++ templates operators default functor

为简单起见,假设我想要实现一个函数,它接受两个参数和谓词测试是否相等,

template<typename T, typename TCompare>
bool Eq(const T& a, const T& b, const TCompare& cmp) {
  return cmp(a, b);
}

但我也希望如果没有传递谓词,则假定operator==

我尝试了几种不同的方法,但都导致语法错误或“operator ==”未定义。我甚至尝试用

替换Eq函数

尽管如此,我想我想要的是可能的,因为STL的大部分支持不传递可选的TCompare参数(std :: sort,std :: set ...)。

更新: 感谢levis501的建议,这是我到目前为止找到的最佳方式:

template<typename T, typename TCompare>
bool Eq(const T& a, const T& b, const TCompare& cmp) {
  return cmp(a, b); // or some lengthy code
}

template<typename T>
bool Eq(const T& a, const T& b) {
  static std::equal_to<T> EqCmp;
  return Eq(a, b, EqCmp);
}

因此,您基本上需要创建一个传递std :: equal_to或任何其他运算符等效函数的包装器。出于某种原因,在没有它的情况下调用函数时,将它作为默认参数不会编译。

3 个答案:

答案 0 :(得分:4)

答案 1 :(得分:1)

你可以重载功能吗?没有?

// Use the user-supplied TCompare.
template<typename T, typename TCompare> 
bool Eq(const T& a, const T& b, TCompare cmp) { 
  return cmp(a, b); 
} 

// Use op== for equality otherwise.
template<typename T> 
bool Eq(const T& a, const T& b) { 
  return a == b; 
} 

如果代码使用三个参数调用Eq(),编译器将解析对第一个重载的调用。如果代码只用两个参数调用Eq(),那么编译器必须解析为第二个重载。

答案 2 :(得分:1)

我认为以下内容对你不起作用:

#include <functional>

template<typename T, typename TCompare = std::equal_to<T>>
class Math {
public:
    static bool Eq(const T& a, const T& b) {
        TCompare cmp;

        return cmp(a, b);
    }
};

int _tmain(int argc, _TCHAR* argv[]) {
    Math<int>::Eq(1,1);

    return 0;
}

默认模板参数仅允许在类模板上(或者至少是MSVC 10所说的)