首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >string类继承和冗长的c++重载解析#2

string类继承和冗长的c++重载解析#2
EN

Stack Overflow用户
提问于 2018-11-06 16:38:16
回答 1查看 61关注 0票数 0

前一个问题:std::string class inheritance and tedious c++ overload resolution

在上一个问题之后的几个步骤中,我尝试在原始字符串指针:operator+上测试"aaa" + path_string{ "bbb" }。并发现它不调用相应的path_string类朋友函数。

我试图添加非模板重载的operator+ (2),但它也不起作用。但是我发现模板1 (3)确实起作用了。

代码语言:javascript
运行
复制
#include <string>

template <class t_elem, class t_traits, class t_alloc>
class path_basic_string : public std::basic_string<t_elem, t_traits, t_alloc>
{
public:
    using base_type = std::basic_string<t_elem, t_traits, t_alloc>;

    path_basic_string() = default;
    path_basic_string(const path_basic_string & ) = default;
    path_basic_string(path_basic_string &&) = default;

    path_basic_string & operator =(path_basic_string path_str)
    {
        this->base_type::operator=(std::move(path_str));
        return *this;
    }

    path_basic_string(base_type r) :
        base_type(std::move(r))
    {
    }

    path_basic_string(const t_elem * p) :
        base_type(p)
    {
    }

    base_type & str()
    {
        return *this;
    }

    const base_type & str() const
    {
        return *this;
    }

    using base_type::base_type;
    using base_type::operator=;

    // ... all over operators are removed as not related to the issue ...

    // (1)
    friend path_basic_string operator+ (const t_elem * p, const base_type & r)
    {
        path_basic_string l_path = p;
        l_path += "xxx";
        return std::move(l_path);
    }

    friend path_basic_string operator+ (const t_elem * p, base_type && r)
    {
        if (!r.empty()) {
            return "111" + ("/" + r); // call base operator instead in case if it is specialized for this
        }

        return "111";
    }

    // (2)
    friend path_basic_string operator+ (const t_elem * p, path_basic_string && r)
    {
        base_type && r_path = std::move(std::forward<base_type>(r));
        if (!r_path.empty()) {
            return "222" + ("/" + r_path); // call base operator instead in case if it is specialized for this
        }

        return "222";
    }

    // (3) required here to intercept the second argument
    template <typename T>
    friend path_basic_string operator+ (const t_elem * p, T && r)
    {
        base_type && r_path = std::move(std::forward<base_type>(r));
        if (!r_path.empty()) {
            return "333" + ("/" + r_path); // call base operator instead in case if it is specialized for this
        }

        return "333";
    }
};

using path_string = path_basic_string<char, std::char_traits<char>, std::allocator<char> >;

std::string test_path_string_operator_plus_right_xref(path_string && right_path_str)
{
    return "aaa" + right_path_str;
}

int main()
{
    const path_string test =
        test_path_string_operator_plus_right_xref(std::move(path_string{ "bbb" }));
    printf("-%s-\n", test.str().c_str());

    return 0;
}

3个编译器的输出: gcc 5.4,clang 3.8.0,msvc 2015 (19.00.23506)

-333/bbb-

https://rextester.com/BOFUS59590

正如我所记得的,C++标准澄清了这一点,就像模板函数只有在没有一个没有模板函数匹配的参数完全匹配的情况下才必须进行查找。但是(2)运算符必须是完全匹配的,但是为什么不调用它呢?

如果删除(3),那么(1)将调用而不是(2),这比(1)更匹配。

这里发生什么事情?

PS:我认为这与之前问题中的const + single reference是相同的问题。

EN

回答 1

Stack Overflow用户

发布于 2018-11-06 17:11:21

在下面的片段中:

代码语言:javascript
运行
复制
std::string test_path_string_operator_plus_right_xref(path_string && right_path_str)
{
    return "aaa" + right_path_str;
}

right_path_str是一个非const l-值.因此,它永远不能绑定到rvalue引用。

当模板重载不可用时,它将绑定到

代码语言:javascript
运行
复制
friend path_basic_string operator+ (const t_elem * p, const base_type & r)

当模板存在时,它更适合于非const值引用:

代码语言:javascript
运行
复制
template <typename T>
friend path_basic_string operator+ (const t_elem * p, T && r)

在这种情况下,T&&是一个转发引用,它折叠为非const引用.要修复您的代码,请确保在调用函数时从rvalue引用参数中提取move,并使其成为习惯--每当您在下面传递rvalue引用时,使用std::move,而当您传递转发引用时,则使用std::forward

代码语言:javascript
运行
复制
std::string test_path_string_operator_plus_right_xref(path_string && right_path_str)
{
    return "aaa" + std::move(right_path_str);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53176185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档