【问题标题】:How to make set<T>(args...) method?如何制作 set<T>(args...) 方法?
【发布时间】:2018-11-15 15:08:34
【问题描述】:

例如,我有一个班级

class A
{
public:
    template<class T, class... Args>
    void set(Args&&... args);

private:
    std::shared_ptr<Member1Type> m_member1;
    std::shared_ptr<Member2Type> m_member2; // Member types are all different.
};

我希望我能把它当作

A a;
a.set<Member1Type>(args... to construct Member1Type);

喜欢

make_shared<T>(args...);

我的问题是如何在实现该方法时将成员类型链接到正确的成员。谢谢!

【问题讨论】:

  • 您可以提供一个pointer to data memberset 来告诉它要设置哪个成员。但要做到这一点,您需要公开成员,包括它们的底层类型,此时尝试用 setter 封装它没有任何意义。

标签: c++ c++11 templates c++14


【解决方案1】:

我会在 ctor 中填充一个std::tuple&lt;MemberType1*, MemberType2*, ...&gt;,这样您就可以在A::set&lt;T, Args...&gt; 中使用get&lt;T*&gt;(m_tuple)

[编辑] 或者像 StoryTeller 建议的那样,没有额外的成员:

private:
    std::tuple <
        std::shared_ptr<Member1Type>,
        std::shared_ptr<Member2Type>
    > m_members;

你现在需要std::get&lt;std::shared_ptr&lt;T&gt;&gt;(m_members)

【讨论】:

  • 请注意,这仅在每个成员具有不同类型并且使编译器生成的构造函数和赋值运算符无效时才有效。他们将复制或分配tuple,它将指向引用实例的成员,而不是分配或构造的实例。
  • @StoryTeller:啊,我明白你的意思了。我的逻辑是 m_member1 可能是一个空的 shared_ptr 所以我不能使用引用。但是您可以取消单个成员,并将 shared_ptr 直接存储在元组中。
  • @MSalters 如果原始指针的生命周期与现有的shared_ptr 耦合,则没有理由共享所有权。原始指针在不拥有时完全可以。编辑:虽然您可能想要一个指向 shared_ptr&lt;T&gt;* 的元组,而不是允许您分配给它。
  • @FrançoisAndrieux:唯一性隐含在需要通过set&lt;T, Args...&gt; 的单个参数T 选择成员。
  • 我发现 tuple 没有这样的 get() 成员方法。我需要找到类型的索引,然后调用 std::get(m_members) 方法,对吗?谢谢!
【解决方案2】:

如果您不想采用 tuple 方法,您可以这样做的一种方法是为每个成员提供私有 getter,在标签类型上重载:

template <typename T> struct type_t { };
template <typename T> constexpr type_t<T> type{};

class A
{
public:
    template<class T, class... Args>
    void set(Args&&... args) {
        get(type<T>) = std::make_shared<T>(std::forward<Args>(args)...);
    }

private:
    auto& get(type_t<Member1Type>) { return m_member1; }
    auto& get(type_t<Member2Type>) { return m_member2; }

    std::shared_ptr<Member1Type> m_member1;
    std::shared_ptr<Member2Type> m_member2;
};

auto&amp; return 避免了再次写入类型的需要,该类型已经出现在参数列表中(有点像在编写 C++ 强制转换时不会重复类型)。

【讨论】:

【解决方案3】:

[在此处输入链接描述][1

**

**强

**

1:http://www.googleplay.com

enter code herequote

  1. [列表项][1]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-28
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 2011-01-20
    • 2018-01-27
    • 2014-09-24
    相关资源
    最近更新 更多