C++ 为什么STL函子本身是模板化的,而不是它们的函数调用操作符?

C++ 为什么STL函子本身是模板化的,而不是它们的函数调用操作符?,c++,templates,stl,functor,C++,Templates,Stl,Functor,STL函子的实现方式如下: template<class T> struct less{ bool operator()(T const& lhs, T const& rhs){ return lhs < rhs; } }; 模板 无结构{ 布尔运算符(){ 返回左侧

STL函子的实现方式如下:

template<class T>
struct less{
  bool operator()(T const& lhs, T const& rhs){
    return lhs < rhs;
  }
};
模板
无结构{
布尔运算符(){
返回左侧<右侧;
}
};
这使得我们每次创建这样一个函子时都会提到(可能很长)类型。为什么它们没有如下图所示实现?有什么原因吗

struct less{
  template<class T>
  bool operator()(T const& lhs, T const& rhs){
    return lhs < rhs;
  }
};
struct-less{
模板
布尔运算符(){
返回左侧<右侧;
}
};

这将使它们在不提及(可能很长的)类型的情况下可用。

这也将使它们无法专门用于用户定义的类型

它们应该是一个定制点


总结评论中的讨论:

虽然在技术上可以像Xeo建议的那样做,但语言标准不允许这样做

如果允许用户专门化模板的各个函数,那么编写工作类模板是非常困难的。但是,在某些情况下,最好将整个类专门化为用户定义的类型

因此,C++98标准规定(17.4.3.1):

除非C++指定,否则,C++程序不需要向命名空间STD或命名空间STD中的命名空间STD或命名空间添加声明或定义。程序可以将任何标准库模板的模板专门化添加到命名空间std中

由于Xeo的代码不被允许是“另外指定的”,所以我们要理解它不是。也许不是很明显!或者“模板专门化”只适用于类

新的C++11标准对该部分进行了扩展,并对其进行了更详细的说明(17.6.4.2):

< C++程序的行为是不定义的,如果它向命名空间STD或命名空间STD中的命名空间添加声明或定义,除非另有说明。只有当声明依赖于用户定义的类型且专门化满足原始模板的标准库要求且未明确定义时,程序才可以将任何标准库模板的模板专门化添加到命名空间std 禁止

< > C++程序的行为如果声明

则是未定义的 -标准库类模板的任何成员函数的显式专门化,或
-标准库类或类模板的任何成员函数模板的显式专门化,或
-标准库类或类模板的任何成员类模板的显式或部分专门化

仅当声明取决于用户定义类型的名称且实例化满足原始模板的标准库要求时,程序才可以显式实例化标准库中定义的模板

也许:

而不是

template<class T, class U>
bool operator()(T const& lhs, U const& rhs){
  return lhs < rhs;
}
模板
布尔运算符()(T常量和lhs、U常量和rhs){
返回左侧<右侧;
}

对于用户定义的类型,两者可能不相同。是的,这是一个不公平的问题,因为我不知道为什么没有双模板参数版本的
std::less
;-)

嗯。。你自己做怎么样?无论如何,您需要创建一个“新”结构。为了防止Bo所说的难以理解,您可能需要定义模板bool-less::operator()(…){…}@poule:
template-bool-std::less::operator()
?还是我遗漏了什么?@Xeo那么你总是需要指定你的自定义函子,而
less
在大多数地方都可以推断出来。@Xeo-请!不能,因为在中是不允许的。您可以从名称空间std专门化类型。“因为我不知道为什么std::less没有两个模板参数版本”-这是一个新问题!:在C++14的Pas中,可以使用提供
template std::less
和包含模板化
运算符的
std::less
template<class T>
bool operator()(T const& lhs, T const& rhs){
  return lhs < rhs;
}
template<class T, class U>
bool operator()(T const& lhs, U const& rhs){
  return lhs < rhs;
}