gpt4 book ai didi

c++ - 使用表达式模板时,根据左值/右值提供类的不同实现

转载 作者:IT老高 更新时间:2023-10-28 21:53:06 25 4
gpt4 key购买 nike

问题

假设我们实现了 string代表,嗯,字符串的类。然后我们想添加一个 operator+连接两个 string s,并决定通过 表达式模板 来实现,以避免在执行 str1 + str2 + ... + strN 时进行多次分配.

运算符将如下所示:

stringbuilder<string, string> operator+(const string &a, const string &b)

stringbuilder是一个模板类,它反过来重载 operator+并且有一个隐含的 string转换运算符。几乎是标准的教科书练习:

template<class T, class U> class stringbuilder;

template<> class stringbuilder<string, string> {
stringbuilder(const string &a, const string &b) : a(a), b(b) {};
const string &a;
const string &b;
operator string() const;
// ...
}

// recursive case similar,
// building a stringbuilder<stringbuilder<...>, string>

只要有人这样做,上述实现就可以完美运行

string result = str1 + str2 + ... + strN;

但是,它有一个微妙的错误。将结果分配给 right 类型的变量将使该变量保存对构成表达式的所有字符串的引用。这意味着,例如,更改其中一个字符串会改变结果:

void print(string);
string str1 = "foo";
string str2 = "bar";
right_type result = str1 + str2;
str1 = "fie";
print(result);

这将打印 fiebar,因为 str1 引用存储在表达式模板中。情况变得更糟:

string f();
right_type result = str1 + f();
print(result); // kaboom

现在表达式模板将包含对已破坏值的引用,立即使您的程序崩溃

现在是什么 right_type ?当然是 stringbuilder<stringbuilder<...>, string> ,即表达式模板魔法为我们生成的类型。

现在为什么要使用这样的隐藏类型?事实上,人们并没有明确地使用它——但 C++11 的 auto 可以!

auto result = str1 + str2 + ... + strN; // guess what's going on here?

问题

底线是:似乎这种实现表达式模板的方式(通过存储廉价引用而不是复制值或使用共享指针)一旦尝试存储就会被破坏 表达式模板本身。

因此,我非常想要一种方法来检测我是在构建右值还是左值,并根据具体情况提供表达式模板的不同实现是构建右值(保留引用)还是构建左值(制作拷贝)。

是否有成熟的设计模式来处理这种情况?

在我的研究过程中,我唯一能弄清楚的是

  1. 可以根据 this 重载成员函数是左值或右值,即

    class C {
    void f() &;
    void f() &&; // called on temporaries
    }

    但是,我似乎也不能在构造函数上这样做。

  2. 在 C++ 中不能真正做到``类型重载'',即提供同一类型的多个实现,这取决于类型将如何使用 strong>(作为左值或右值创建的实例)。

最佳答案

我在评论中开始了这个,但它有点大。然后,让它成为一个答案(即使它并没有真正回答你的问题)。

这是 auto 的一个已知问题。例如,Herb Sutter here 已经讨论过它。 Motti Lanzkron here 提供更多详细信息.

正如他们所说,委员会曾讨论将 operator auto 添加到 C++ 以解决此问题。这个想法将代替(或除此之外)提供

operator string() const;

正如你提到的,有人会提供

string operator auto() const;

用于类型推导上下文。在这种情况下,

auto result = str1 + str2 + ... + strN;

不会推断出 result 的类型是“正确的类型”,而是类型 string 因为这就是 operator auto()返回。

AFAICT 这在 C++14 中不会发生。 C++17 可能...

关于c++ - 使用表达式模板时,根据左值/右值提供类的不同实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17796718/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com