Можно ли хранить ссылку в std :: any? - PullRequest
1 голос
/ 15 июня 2019

Я пытался кое-что и пришел к следующему вопросу: есть ли возможность хранить ссылки на значение в std::any?

Я попробовал следующие подходы:

#include <any>
#include <iostream>
#include <functional>

auto func_by_pointer(std::any obj)
{
    *std::any_cast<int *>(obj) += 2;
}
auto modify_by_pointer(int &a)
{
    func_by_pointer(std::make_any<int *>(&a));
}

auto func_by_reference_wrapper(std::any obj)
{
    std::any_cast<std::reference_wrapper<int>>(obj).get() -= 2;
}
auto modify_by_reference_wrapper(int &a)
{
    func_by_reference_wrapper(std::make_any<std::reference_wrapper<int>>(a));
}

auto func_by_reference(std::any obj)
{
    std::any_cast<int &>(obj) *= 2;
}
auto modify_by_reference(int &a)
{
    func_by_reference(std::make_any<int &>(a));
}

int main()
{
    auto value = 3;
    std::cout << value << '\n';
    modify_by_pointer(value);
    std::cout << value << '\n';
    modify_by_reference_wrapper(value);
    std::cout << value << '\n';
    modify_by_reference(value);
    std::cout << value << '\n';
}

Результатом является следующий вывод:

3
5
3
3

Тем не менее, я ожидал, что он будет:

3
5
3
6

Таким образом, передача указателя на value работает нормально.Передача std::reference_wrapper в value также работает нормально, но передача int& как-то не работает.Я сделал что-то не так в своем коде, или вообще невозможно хранить ссылки внутри std::any?

1 Ответ

4 голосов
/ 15 июня 2019

Нельзя хранить ссылки в std::any, поскольку для данного типа T конструктор std::any(T) хранит значение типа std::decay_t<T>, которое удаляет квалификаторы ссылок:

[any.cons]

template<class T>
  any(T&& value);
  1. Пусть VT будет decay_­t<T>.

  2. Требуется: VT должен удовлетворять Cpp17CopyConstructible требованиям.

  3. Эффекты: Создает объект типа any, который содержит объект типа VT с прямой инициализацией std::forward<T>(value).

...