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&
之间的区别,所以我不想在这里进行不必要的混合。。。