1

比方说,我有一个std::any商店类型 T 。是否可以创建另一个std::any包含 type std::reference_wrapper<const T>?喜欢

std::any original = std::string("Test string");
std::any reference;

// Magic here

auto ref = std::any_cast<std::reference_wrapper<const std::string>>(reference); // Works
4

3 回答 3

1

这是不可能的,除非您知道确切的存储类型(请参阅其他答案)或可能类型的列表(在这种情况下您可以switchover original.type())。

于 2020-01-08T19:11:00.067 回答
1

如果你非常想要这个,你可以围绕 a 创建一个小包装类,它在构造时std::any捕获并类型擦除“转换为”操作:reference_wrapper

class any_refable
{
public:
    std::any ref() const { return converter(any); }

    const std::any& get() const& { return any; }
    const std::any&& get() const&& { return std::move(any); }
    std::any& get() & { return any; }
    std::any&& get() && { return std::move(any); }

    any_refable() = default;

    template <typename T, typename = std::enable_if_t<! std::is_same_v<std::decay_t<T>, any_refable>>>
    any_refable(T&& v) : any(std::forward<T>(v)), converter(make_converter<std::decay_t<T>>()) {}

    template <typename T, typename = std::enable_if_t<! std::is_same_v<std::decay_t<T>, any_refable>>>
    any_refable& operator=(T&& v) { any = std::forward<T>(v); converter = make_converter<std::decay_t<T>>(); return *this; }

private:
    using converter_t = std::any (*)(const std::any&);

    std::any any;
    converter_t converter = nullptr;

    template <typename T>
    static converter_t make_converter() {
        return [](const std::any& any) { return std::any(std::cref(std::any_cast<const T&>(any))); };
    }
};

演示

于 2020-01-08T20:30:51.973 回答
0

以下作品:

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

int main() {
    std::any original = std::string("Test string");
    std::any ref = std::cref(std::any_cast<const std::string&>(original)); 

    std::any_cast<std::string&>(original)[0] = 'X';

    std::cout << std::any_cast<std::reference_wrapper<const std::string>>(ref).get() << '\n'; // Prints Xest string
}

编辑:正如评论中所说,这仅在编译时已知类型时才有效。如果包含的对象的类型是任意的,这是不可能的,因为std::reference_wrapper必须在某个时候构造,为此它需要知道它必须在编译时包装的类型,因为 C++ 是静态的,所以没有办法解决这个问题打字。

于 2020-01-08T19:01:53.370 回答