运算符错误<过载,操作数无效

时间:2013-03-12 21:21:07

标签: c++ templates operator-overloading

当我尝试使用这样的代码时:

namespace
{
    typedef boost::shared_ptr< float >  sharedFloat;
}

static bool operator<( const sharedFloat& inOne, float inTwo )
{
    return *inOne < inTwo;
}

static void foo()
{
    std::vector< sharedFloat > theVec;
    std::vector< sharedFloat >::iterator i =
        std::lower_bound( theVec.begin(), theVec.end(), 3.4f );
}

我收到错误:

error: invalid operands to binary expression ('boost::shared_ptr<float>' and 'float')

(指向&lt; lower_bound实现中的比较。)那么,当我提供operator<这些操作数时,为什么它们无效?

如果我改为使用比较函子,

namespace
{
    typedef boost::shared_ptr< float >  sharedFloat;

    struct Comp
    {
        bool operator()( const sharedFloat& inOne, float inTwo )
        {
            return *inOne < inTwo;
        }
    };
}

static void foo()
{
    std::vector< sharedFloat > theVec;
    std::vector< sharedFloat >::iterator i =
        std::lower_bound( theVec.begin(), theVec.end(), 3.4f, Comp() );
}

然后编译。我可以这样做,但我想知道为什么第一次尝试失败了。

在解决方案之后添加: Namespaces & Interface Principle由Herb Sutter帮助我更多地澄清这些内容。

2 个答案:

答案 0 :(得分:4)

operator<无法找到lower_bound,因为它不在与您使用的类型相关联的任何名称空间中。

编译器将查找名称空间stdboost,但不会查找全局名称空间,因为没有涉及的内容。

当你传递Comp explicilty时,它有效,因为编译器不必搜索匹配的运算符。

答案 1 :(得分:3)

operator <的调用是在std命名空间内执行的。因此,编译器将在operator <命名空间和其参数的命名空间(ADL)中查找std的适当重载。如果找到一个运算符(即使它不可行!),则封闭名称空间搜索。

由于在全局命名空间中定义了operator <,编译器不会考虑它(因为operator <命名空间中存在另一个重载std,并且在名称查找之前可以考虑封闭命名空间)。

最后,由于std::operator <不可行,编译器将发出错误。

当你将自己的仿函数作为最后一个参数传递时,事情显然是不同的:不是寻找可行的operator <,而是调用参数本身,并且一切都编译得很好。