C++ 变量-为什么模板参数的优先级高于常量字符串参数
我在下面的代码中看到了我不理解的行为。关键是,如果我声明C++ 变量-为什么模板参数的优先级高于常量字符串参数,c++,templates,boost,boost-variant,C++,Templates,Boost,Boost Variant,我在下面的代码中看到了我不理解的行为。关键是,如果我声明操作符()的第二个重载,如下所示: bool operator()(T other) const bool operator()(const T &other) const 程序的输出为: 串 但如果我使用以下声明: bool operator()(T &other) const 输出将是: 其他类型 有人能解释一下为什么在后一种情况下没有调用operator()(const string&other) #include
操作符()
的第二个重载,如下所示:
bool operator()(T other) const
bool operator()(const T &other) const
程序的输出为:
串
但如果我使用以下声明:
bool operator()(T &other) const
输出将是:
其他类型
有人能解释一下为什么在后一种情况下没有调用operator()(const string&other)
#include "boost/variant/variant.hpp"
#include "boost/variant/apply_visitor.hpp"
using namespace std;
using namespace boost;
typedef variant<string, int> MyVariant;
class StartsWith
: public boost::static_visitor<bool>
{
public:
string mPrefix;
bool operator()(const string &other) const
{
cout << "string" << endl;
return other.compare(0, mPrefix.length(), mPrefix) == 0;
}
template<typename T>
bool operator()(T &other) const
{
cout << "other type" << endl;
return false;
}
StartsWith(string const& prefix):mPrefix(prefix){}
};
int main(int argc, char **argv)
{
MyVariant v(string("123456"));
apply_visitor(StartsWith("123"), v);
return 0;
}
#包括“boost/variant/variant.hpp”
#包括“boost/variant/apply_visitor.hpp”
使用名称空间std;
使用名称空间boost;
typedef变异体MyVariant;
类StartsWith
:public boost::static\u访问者
{
公众:
字符串mPrefix;
布尔运算符()(常量字符串和其他)常量
{
您这里有const
问题
您正在将not const对象传递给apply\u visitor
-因此not const对象成员将传递给applied visitor。因此,在您的情况下,它是string&
-对字符串类型的引用。此模板与其完全匹配:
template<typename T>
bool operator()(T &other) const
当然,如果您提供该操作员:
bool operator()(string &other) const
bool operator()(/*const*/ string &other) const
// ^^^^^^^^^ remove it
然后选择它,因为在模板1之前考虑非模板函数
所以解决方案是:要么在访问者中提供获取字符串引用(而不是常量)的方法,要么传递常量变量以应用
第一种解决方案-从字符串运算符中删除常量:
bool operator()(string &other) const
bool operator()(/*const*/ string &other) const
// ^^^^^^^^^ remove it
第二种解决方案-传递常量对象:
const MyVariant& cv = v;
apply_visitor(StartsWith("123"), cv);
// ^^ const object passed here
第三种解决方案-向普通访问者添加常量说明符:
template<typename T>
bool operator()(const T &other) const
// ^^^^^
模板
布尔运算符()(常数T和其他)常数
// ^^^^^
第1种和第3种解决方案比第2种更好-您应该将一致的访问者传递给您的变体,当编译器必须选择适当的函数时,const具有很强的意义。作为一个类型怪胎,我想说第3种解决方案是最好的,如:const correct。如果您不打算o修改它。@MatthieuM。在这种情况下,你是对的。我没有提到T&&
-可能这是最好的-但是有很多帖子讨论T&&
和const T&
之间的区别,所以我不想在这里进行不必要的混合。。。