c++ - boost::variant - 为什么模板参数的优先级高于 const 字符串参数

标签 c++ templates boost boost-variant

我在以下代码中看到一个我不理解的行为。关键是,如果我声明 operator() 的第二个重载,如下所示:

bool operator()(T other) const
bool operator()(const T &other) const

程序的输出是:

string

但是如果我使用下面的声明:

bool operator()(T &other) const

输出将是:

other type

有人可以解释一下为什么在后一种情况下没有调用 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;
}

最佳答案

这里有const问题。

您将非常量对象传递给 apply_visitor - 因此非常量对象成员将传递给应用的访问者。所以在你的情况下它是 string& - 对字符串类型的引用。此模板与其完全匹配:

template<typename T>
bool operator()(T &other) const

所以被选中了。此函数不完全匹配 - 它被跳过:

bool operator()(const string &other) const

当然,如果您提供该运算符:

bool operator()(string &other) const

那么它将被选中,因为非模板函数在模板一之前被考虑。

所以解决方案是:要么在您的访问者中提供采用字符串引用(不是 const)的方法 - 或者传递 const 变体以应用...

第一个解决方案 - 从字符串运算符中删除 const:

bool operator()(/*const*/ string &other) const
//              ^^^^^^^^^ remove it

第二种解决方案 - 传递 const 对象:

const MyVariant& cv = v;
apply_visitor(StartsWith("123"), cv);
//                               ^^ const object passed here

方案三——给普通访问者添加const说明符:

template<typename T>
bool operator()(const T &other) const
//              ^^^^^ 

解决方案 1 和 3 比 2 好 - 你应该将一致的访问者传递给你的变体,当编译器必须选择适当的函数时,const 具有很强的意义。

关于c++ - boost::variant - 为什么模板参数的优先级高于 const 字符串参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13320145/

相关文章:

c++ - 获取模板参数的 decltype

c++ - 动态模板数组

c++ - 实现观察者模式时出现问题 : "Member reference base type ________ is not a structure or union"

regex - 如何使用 XCode 构建 boost "Getting Started"示例?

c++ - 如何从数据集中读取特定的字符列

c++ - 具有动态行数和固定列数的二维数组的初始化。 C++

c++ - 我应该如何为我的类编写构造函数

c++ - 上证所该向上舍入时向下舍入

c++ - 强制删除 boost::signals2 中的插槽

c++ - 比较 boost 功能 - 功能签名?