C++ 如何强制编译器选择特定的函数专门化
例如,我有两门课:C++ 如何强制编译器选择特定的函数专门化,c++,templates,C++,Templates,例如,我有两门课: class Foo { public: const bool operator==(const Foo&) const; template<class _Ty> const bool operator==(const _Ty&) const; }; class Bar : public Foo { }; 显然,编译器将选择模板函数来计算此表达式,因为变量bar需要转换为Foo&来调用专门的运算符==。但是,当参数是从F
class Foo {
public:
const bool operator==(const Foo&) const;
template<class _Ty>
const bool operator==(const _Ty&) const;
};
class Bar : public Foo { };
显然,编译器将选择模板函数来计算此表达式,因为变量bar
需要转换为Foo&
来调用专门的运算符==
。但是,当参数是从Foo
派生的类的实例时(例如添加/删除一些修饰符或其他内容),有没有办法强制编译器(无需将Bar&
强制转换为Foo&
)首先选择专门化而不是模板函数
当参数是从Foo派生的类的实例时,有没有办法强制编译器(无需将Bar&强制转换为Foo&)首先选择专门化而不是模板函数
是的,你可以,使用类型特征。具体而言,您可以使用和,如下所示:
template<typename Type>
typename std::enable_if<
std::is_base_of<Foo, Type>::value,
const bool
>::type
operator==(const Type&) const { … }
template<typename Type>
typename std::enable_if<
!std::is_base_of<Foo, Type>::value,
const bool
>::type
operator==(const Type&) const { … }
模板
typename std::启用\u如果<
std::是::value的_base,
康斯特布尔
>::类型
运算符==(常量类型&)常量{…}
模板
typename std::启用\u如果<
!std::是::value的_base,
康斯特布尔
>::类型
运算符==(常量类型&)常量{…}
基本上可以根据模板参数激活/停用重载
还可以通过添加别名使内容更具可读性:
template<class Type>
using is_fooable = std::is_base_of<Foo, Type>;
模板
使用is_fooable=std::is_base_of;
你可以试着将Bar转换成Foo。@Chnossos是的,我可以。但实际上问题是关于这个表达式,而不是将
Bar&
转换为Foo&
:)@Chnossos我对问题进行了编辑以澄清问题。在没有强制转换的情况下,我想到的唯一解决方案是更改第一个函数,使其成为第二个函数的特化,用于Foo类型,然后调用您的比较,如Foo.operator==(bar)
但这有点难看…@Chnossos另一个方法是只保留模板运算符,它将调用私有比较函数(该函数将以与问题中的运算符相同的方式声明,但使用一些伪参数来更改它们的优先级)。但我不知道这是否真的是一个好的解决方案。+1:但我自己,我会将参数标记为分派到bool equal(Foo const&,std::true_type)
和bool equal(t const&,std::false_type)
,因为这样就删除了条实现中不必要的模板ing。噢,const
在错误的位置——你想返回bool
,但以const
对象实例为例。@Yakk,你所说的const
在错误的位置是什么意思呢?你函数的返回值应该是bool
而不是const bool
——有非常,返回const
值类型的有效理由很少。@Yakk,嗯。你为什么要重新分配那个临时对象(由x==y
返回的对象)?IIRC,在他的一本书中,Scott Meyer推荐了这种做法。如果是基本类型,没有区别。如果是非基本的,const
阻止有效的move
退出临时移动(如果移动未被省略)。相反,阻止operator=
使用左值lhs(模拟基本类型)进行操作。
template<class Type>
using is_fooable = std::is_base_of<Foo, Type>;