У меня есть функция, которая возвращает временный объект, который содержит ссылку внутри, и его единственная цель - разрешить своего рода перегрузку возвращаемого типа. Например:
#include <iostream>
#include <vector>
class MyData {
private:
class IntOrChar {
public:
IntOrChar(char const& c) : c_(c) {}
operator char() { return c_; }
operator int() { return c_-'0'; }
private:
char const& c_;
};
public:
MyData(std::string number) : number_(number) {}
IntOrChar get(std::size_t i) { return number_[i]; }
private:
std::string number_;
};
void accepts_char(char c) { std::cout << "char: " << c << '\n'; }
void accepts_int(int i) { std::cout << "int: " << i << '\n'; }
int main(){
MyData n("012345");
accepts_char(n.get(3));
accepts_int(n.get(3));
}
Фактический код более сложен, и он ссылается на какое-то внутреннее состояние.
Используя приведенный выше пример, могу ли я предотвратить сохранение значения, возвращаемого get()? Я хочу предотвратить такой код:
MyData n("0123");
auto r = n.get(2);
... // much later in the code
accepts_char(r);
поскольку в точке, где он используется, внутренняя ссылка может быть уже недействительной. Я хочу, чтобы класс приведения (IntOrChar) был немедленно приведен к конкретному типу, а не удерживался.
Я думаю, что условия, которые я ищу, заключаются в том, что я хочу предотвратить превращение prvalue в xvalue?
Я просто хочу, чтобы это не было сделано случайно. Меня не волнует, можно ли это обойти, используя какой-то тип принудительного заклинания или другое волшебство.
У меня есть функция, которая возвращает временный объект, который содержит ссылку внутри Хммм, не могу сказать, что мне нравится эта идея. Это опасно.





Обходной путь — сделать функции преобразования &&-квалифицированными. Всем, кто спросит, почему они должны писать accepts_char(std::move(r)), можно напомнить о назначении шрифта.
Реальный ответ — пометить тип как пожизненный, но это все еще предложение . Другая возможность для точного приведенного примера — сделать auto неудачным для типа, но это также просто предложение.
В С++ для этого ничего нет. Максимум, что можно сделать, это предотвратить вызов метода для объекта prvalue, но никак не запретить сохранение prvalue.