c++ - 强制 "in-place" build

标签 c++

足够简单的代码,其中 bar 有一个 foo 类型的成员:

struct foo {
  foo(int some, int parameters) {}
};

struct bar {
  foo f;
  bar(foo f_) { f = f_; }
}

如何更改它以便 bar 可以foo “就地”初始化,例如像这样?

foo f;
bar b1(f); //error
bar b2(1,2); //works!

目的是有时我正在处理无法复制的类 foo,这样做会使意图清晰。

最佳答案

正如@KerrekSB 提到的,最简单的方法是复制 foobar 中的构造函数:

bar(int a, int b) : f(a, b) {}

然而,当 foo 时,这很快就变得不切实际了。有大量的构造函数,如果 bar 甚至可能是不可能的是 template<typename T>并且您想对任何可能的 T 执行此操作.


进入C++11的完美转发:

template<typename... Args>
bar(Args&&... args) : f(std::forward<Args>(args)...) {}

这允许您的 bar构造函数将它接收到的任何参数直接转发给 foo构造函数,就像 emplace C++11 标准库中的方法。


现在还有一个问题:因为你的 bar构造函数接受您的 foo任何 参数构造函数接受,显然如果 foo然后有一个复制构造函数 bar会接受它:

bar b1(1, 2); // ok
foo f(1, 2);
bar b2(f);    // ok too!

诀窍是删除相关的构造函数:

struct bar {
    foo f;

    template<typename... Args>
    bar(Args&&... args) : f(std::forward<Args>(args)...) {}

    bar(const foo&) = delete;
    bar(foo&) = delete;
};

foo f(1, 2);
bar b2(f);    // error: use of deleted function ‘bar::bar(foo&)’

请注意,我故意没有删除移动构造函数,因为我假设您禁用复制的动机是性能。这样你仍然可以写:

foo f(1, 2);
bar b1(std::move(f)); // move: ok
bar b2(foo(1, 2));    // temporary: ok (it is really moved)

当然,如果你也想删除移动构造函数,那非常简单:

struct bar {
    foo f;

    template<typename... Args>
    bar(Args&&... args) : f(std::forward<Args>(args)...) {}

    bar(const foo&) = delete;
    bar(foo&) = delete;
    bar(foo&&) = delete;
};

foo f(1, 2);
bar b1(std::move(f)); // error: use of deleted function ‘bar::bar(foo&&)’
bar b2(foo(1, 2));    // error: use of deleted function ‘bar::bar(foo&&)’

特质:我不知道为什么,但即使在 bar 中删除了移动构造函数, 它仍然接受默认构造的临时 (GCC 4.7):

bar b3(foo()); // WTH, this works

我错过一定有充分的理由,但我不知道这里到底发生了什么。如果有人能阐明这一点......

关于c++ - 强制 "in-place" build ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726378/

相关文章:

c++ - 如何检测我的应用程序是作为服务运行还是在交互式 session 中运行?

c++ - SEGFAULT - 在 C++ 纯虚拟机上。为什么?

c++ - 段错误错误 11 C++

c++ - 使用terminos进行规范的串行读取失败?

c++ - 使用 IO 机械手以十六进制打印 8 位数字

c++ - STL Map - 何时使用自定义比较器?

c++ - 在库中隐藏模板函数声明

c++ - Arduino 十六进制转十进制

c++ - 什么时候整数到浮点转换无损?

c++ - 有没有办法通过类型单独获取 vector 的字节大小?