【问题标题】:make_pair like trick for noncopyable classesmake_pair 类似于不可复制类的技巧
【发布时间】:2012-07-26 14:13:18
【问题描述】:

make_pair 可以在不提及类型的情况下创建对。我想对我的类使用相同的技巧,但它继承自 boost::noncopyable,因此无法编译:

template<class Iter>
struct bit_writer : boost:noncopyable
{
    Iter iter;
    bit_writer(Iter iter)
    : iter(iter)
    {}
};

template<class Iter>
bit_writer<Iter> make_bit_writer(Iter iter)
{
    return bit_writer<Iter>(iter);
}
vector<char> vec;
auto w = make_bit_writer(vec);

还有其他选择吗?我试着让 make_bit_writer 成为朋友,然后就没有了想法。

【问题讨论】:

  • 假设您不想通过某种指针(最好是智能指针)返回,是否可以使 bit_writer 成为仅移动类?实际上,您基本上是在告诉编译器创建一个临时文件并将其返回,但该临时文件既不能移动也不能复制。
  • 你试过宏吗? :-D(开个玩笑……)

标签: c++ std-pair noncopyable


【解决方案1】:

如果你有 C++11,你可以使用类似的东西来做到这一点:

#include <functional>
#include <utility>
#include <type_traits>

struct noncopyable_but_still_moveable {
  noncopyable_but_still_moveable(const noncopyable_but_still_moveable&) = delete;
  noncopyable_but_still_moveable(noncopyable_but_still_moveable&&) = default;
  noncopyable_but_still_moveable() = default;
  noncopyable_but_still_moveable& operator=(const noncopyable_but_still_moveable&) = default;
  noncopyable_but_still_moveable& operator=(noncopyable_but_still_moveable&&) = default;
};

template <typename T>
struct test : noncopyable_but_still_moveable {
  test(T) {}
  // the rest is irrelevant 
};

template <typename T>
test<T> make_test(T&& val) {
  return test<typename std::remove_reference<T>::type>(std::forward<T>(val));
}

int main() {
  auto && w = make_test(0);
}

请注意,我已将 boost::noncopyable 替换为具有已删除复制构造函数的类型。这是使某些东西不可复制的 C++11 方法,并且是必需的,因为 boost 类也是不可移动的。当然,您可以将其放在类本身中,不再继承。

如果没有 C++11,您将需要使用 Boost move 之类的东西来模拟这些语义。

【讨论】:

  • 我把你的最后一行改成了 auto&& w = make_test(0);所以我可以在 w 上调用非 const 成员。更改安全吗?
  • 如果 w 是 const 我不能调用非 const 成员。
  • @BrunoMartinez - 已更新。原来我的答案最初是错误的。来自 C++ 聊天室的一些意见帮助解决了这个问题。
【解决方案2】:

您将需要 C++11 并更新您的类以实现移动语义。建议的问题没有其他解决方案。

class test {
public:
    test(test&&);
    // stuff
};
test make_test(...) {
    return test(...);
}
int main() {
    // Both valid:
    auto p = make_test(...);
    auto&& p2 = make_test(...);
} 

【讨论】:

    猜你喜欢
    • 2015-03-15
    • 2015-05-17
    • 2010-12-21
    • 2021-03-01
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多