std :: any用于无法复制构造的对象

Geo*_*rge 6 c++ templates template-meta-programming c++17

我有一个持有unique_ptr的对象,因此不能进行复制而不进行深度复制(我不想要).

我想让std :: any持有那个对象,但我发现的唯一选择是让std :: any保持一个指针,这会增加一个无用的间接,或者使我的对象有一个唯一的ptr.下面的代码有望说明我的观点:

//Compiled with clang++ -std=c++2a; clang version 5.0.0
#include <iostream>
#include <any>
#include <memory>

struct A {
        std::unique_ptr<int> m = std::make_unique<int>(11);
        A(A&& a): m(std::move(a.m)) {}
        A() {}
};

struct B {
        std::shared_ptr<int> m = std::make_shared<int>(11);
};


template<class T>
void use_any_ptr() {
        std::any a{new T{}};
        std::cout << *(std::any_cast<T*>(a)->m) << std::endl;
}

template<class T>
void use_any() {
        std::any a{T{}};
        std::cout << *(std::any_cast<T>(a).m) << std::endl;
}


int main() {
        use_any_ptr<A>(); // Workaround using a pointer
        use_any<B>(); // Workaround using shared pointer
        use_any<A>(); // Breaks because A has no cc no matching constructor for initialization of 'std::any'
}
Run Code Online (Sandbox Code Playgroud)

据我所知,std :: any的构造似乎需要复制对象,但是我不确定为什么不能简单地移动对象.

有办法解决这个问题吗?也就是说,除了使用shared_ptr之外,这意味着我基本上是为了创建任何对象或传递std :: any指针(这是一个不需要的间接层,因为std ::)来表达"错误的东西".任何持有一个指向该类型的void指针,据我所知.

是否有任何可以在创建时使用move ctr而不是copy ctr的实现?

或者我是愚蠢而不理解这里的"真实"问题?

sky*_*ack 4

或者我很愚蠢,不理解这里的“真正”问题?

这里的问题很简单:有一个复制构造函数因此它要求包含的对象是可复制构造的。std::any

您可以解决此问题的方法是定义一个包含指针的自定义对象,该对象是可复制的,并为其实现正确的逻辑(无论您的情况如何正确,我看不出如何复制 an std::any,因此那里包含的对象拥有一个std::unique_ptr,但也许你可以在你的情况下以某种方式逃脱它)。

否则,重新考虑您的设计并尝试摆脱对std::any. 它确实没有太多用处,也许你可以通过一些模板机器或std::variant其他东西来获得相同的效果

  • @George:“any”不是它所采用的类型的模板。所以 `any` *静态地*有一个复制构造函数。不管你是否调用它,它*必须存在*。因此它必须有一个实现。并且该实现必须能够与可以存储在其中的任何类型一起使用。因此,“any”必须*静态地*要求其内容具有复制构造函数。 (7认同)