1

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 成为朋友,然后没有想法了。

4

2 回答 2

4

如果您有 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之类的东西来模拟这些语义。

于 2012-07-27T21:19:09.263 回答
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(...);
} 
于 2012-08-01T17:50:06.903 回答