【问题标题】:std::any for objects that can't be copy constructedstd::any 用于无法复制构造的对象
【发布时间】:2017-10-20 15:14:38
【问题描述】:

我有一个拥有 unique_ptr 的对象,因此如果不进行深度复制(我不想要),就无法复制构造。

我想让 std::any 持有该对象,但我发现的唯一选择是让 std::any 持有一个指针,这增加了无用的间接性,或者让我的对象具有唯一性点。下面的代码有望说明我的观点:

//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'
}

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

有没有办法解决这个问题?也就是说,除了使用 shared_ptr 之外,这意味着我基本上是在表达“错误的事情”,以便创建任何对象或传递 std::any 指针(这是一个不需要的间接级别,因为 std::据我所知,any 持有一个指向类型的 void 指针)。

是否有任何不同的实现可以在创建时使用移动 ctr 而不是复制 ctr?

还是我很傻,不理解这里的“真正”问题?

【问题讨论】:

    标签: c++ templates c++17 template-meta-programming


    【解决方案1】:

    还是我很傻,不理解这里的“真正”问题?

    问题在这里很简单:std::anya copy constructor,因此它要求包含的对象是可复制构造的。

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

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

    【讨论】:

    • 好吧,好吧,在那种情况下,我误解了这个问题。我认为 std::any 的构造需要一个副本。我认为 std::any 可以在没有复制构造的情况下工作,对吧?那么我应该重写还是使用没有副本 ctr 的 impl ?或者有没有办法从一个类中删除 copy_ctr ?
    • @George 它要求您用来构造它的类型是可复制构造的。它使用特征(即std::is_copy_constructible)对其进行检查。
    • @George 无法从std::any 中删除要求。您可以实现 your any 或重新考虑您的设计。实际上,我会选择第二个。
    • 是的,我明白了。但是,如果我从不使用 std::any 的复制 ctr,理论上我可以在不需要复制 ctr 的情况下使用它(并且隐式不需要保存在里面的对象的 cctr)。
    • @George:any 不是它所采用的类型的模板。所以any statically 有一个复制构造函数。不管你是否调用它,它必须存在。因此它必须有一个实现。并且该实现必须能够与可以存储在其中的任何类型一起使用。因此,any 必须静态地要求其内容具有复制构造函数。
    猜你喜欢
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 2018-03-03
    • 2021-03-17
    • 2011-10-17
    • 2018-04-13
    相关资源
    最近更新 更多