重新定义<运算符用于字符串

时间:2017-06-06 13:03:43

标签: c++ templates operator-overloading std

是否可以在不修改std名称空间的情况下为字符串重新定义operator <,以使此运算符在标准算法中使用? 例如,我可以写:

namespace std
{

    bool operator <(const std::string & rhs, const std::string & lhs)
    {
        std::cout << "lol";
        return false;
    }

}

int main()
{
    std::vector<std::string> lol = { "a", "b", "ba", "aa" };
    std::sort(lol.begin(), lol.end());
}

和&#34; lol&#34;将被打印几次。但是如果我将operator <移到std命名空间之外,将使用默认operator <并且不会打印任何内容。是否可以使用自定义std::sort进行operator <而不将其包含在std命名空间中?

是的我知道,我可以将另一个比较器传递给std :: sort但是如果我可以做我所问的以及如何做的话对我有意义吗?

我也是正确的,将这样的模板特化添加到std命名空间是正确的吗?

更新:这不是一个实际问题,我只是想知道如果可能的话我该怎么做。

2 个答案:

答案 0 :(得分:7)

不,不是。向标准命名空间添加函数是未定义的行为。 [namespace.std] / 1州:

  

如果C ++程序向命名空间std或命名空间std中的命名空间添加声明或定义,则该行为是未定义的,除非另有说明。只有当声明取决于用户定义的类型且专业化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std。

如果你想改变std::sort排序方式,那么你可以提供一个lambda并定义你想要的东西

std::sort(std::begin(foo), std::end(foo), [](const auto& lhs, const auto& rhs) { /* your code here */ });

答案 1 :(得分:6)

  

是否可以重新定义运算符&lt;对于没有修改std名称空间的字符串

您可以在另一个命名空间中定义重载。但是,正如您所发现的那样,除非明确限定,否则无法通过重载决策找到它。

  

是否可以使用自定义运算符生成std :: sort&lt;不包括它到std命名空间?

是的,您似乎已经知道如何:

  

是的我知道,我可以将另一个比较器传递给std :: sort

这正是比较器参数的用途。

  

我也是正确的,将这种模板专门化添加到std命名空间的核心是什么?

这不是模板专业化;它是一个函数定义,您可能不会将函数定义添加到std命名空间 - 否则行为是未定义的。您可以添加模板特化,但前提是至少有一个类型参数是用户定义的类型。