указатель на rvalue - PullRequest
       34

указатель на rvalue

0 голосов
/ 06 марта 2012

При поиске решения для вызова функции, которая принимает ссылки как на lvalue, так и на rvalue, я написал следующий фрагмент кода (нет, я обещаю, что никогда больше этого не сделаю).

Цель состояла в том, чтобы предоставить функцию, которая одновременно принимает ссылки на lvalue и rvalue, я не хотел писать две функции или действительно заботиться о lvalue / rvalue на стороне вызывающей стороны. Поэтому я подумал о предоставлении некоторого макроса / функции, которая обернет параметр, чтобы его можно было передать независимо от того, является ли оно значением l / r - в данном случае get_addr.

Ни в коем случае я не хочу изменять данные, передаваемые в функцию.

template<typename T>
std::shared_ptr<T> get_addr(T t) {
    std::shared_ptr<T> p(new T(t));
    return p;
}

int get_value(int x){
    return x * 2;
}

void print_value(int* p){
    cout << *p << endl;
}

int main() {
    print_value(get_addr(get_value(42)).get());
}

Хотя этот код работает нормально для меня, я сомневаюсь, что это безопасно. Мое предположение: после вызова get () из shared_ptr результат get_value () больше не нужен и может быть отклонен. Таким образом, print_value может получить недопустимую ссылку. Имеет ли это смысл? В любом случае мне не нравится мой код. Я решил проблему с помощью временной переменной.

Тем не менее, мне все еще интересно, есть ли лучшее решение для этой проблемы. С точки зрения синтаксиса, я бы предпочел только одну функцию "void print_value (int && p)", которая принимает оба значения l / r. Я посмотрел на семантику перемещения, преобразования l / rvalue, но не нашел решения, которое действительно выглядит красиво.

Ответы [ 2 ]

3 голосов
/ 06 марта 2012

Ни в коем случае я не хотел бы изменять данные, передаваемые в функцию.

Что тогда с этим не так?

void print_value(int p){
    cout << p << endl;
}

Или следующее, если выне хочу копировать какой-нибудь дорогой тип.

void print_value(T const& p){
    cout << p << endl;
}
1 голос
/ 06 марта 2012

Во-первых, вы можете просто взять const T&, и он будет привязан как к значениям l, так и к r. Однако, более прямо, «Perfect Forwarding» является решением этой проблемы.

...