相关疑难解决方法(0)

使用C++ 11中显式删除的成员函数,是否仍然值得从不可复制的基类继承?

使用C++ 11中显式删除的成员函数,是否仍然值得从不可复制的基类继承?

我在谈论私有继承基类的技巧,该基类具有私有或删除的复制构造函数和复制赋值(例如boost::noncopyable).

这个问题提出的优势是否仍适用于C++ 11?


我不明白为什么有些人声称在C++ 11中使类不可复制更容易.

在C++ 03中:

private:
    MyClass(const MyClass&) {}
    MyClass& operator=(const MyClass&) {}
Run Code Online (Sandbox Code Playgroud)

在C++ 11中:

MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
Run Code Online (Sandbox Code Playgroud)

编辑:

正如许多人所指出的那样,为私有拷贝构造函数和拷贝赋值运算符提供空体(即{})是错误的,因为这将允许类本身调用那些运算符而没有任何错误.我首先开始没有添加{},但遇到了一些链接器问题,这些问题让我添加{}有些愚蠢的原因(我不记得这些情况).我知道更清楚.:-)

c++ noncopyable c++11

58
推荐指数
4
解决办法
3万
查看次数

为什么删除移动构造函数时不会复制我的对象?

我正在尝试使用此代码来演示复制构造函数的用法.我的假设是,当我有一个按值返回的函数时,默认情况下,我的编译器将执行对象的移动.但是当move-constructor不可用时,编译器将复制(在C++ 03中,编译器在返回by-value时会复制).那么为什么在下面的例子中编译器会尝试调用显式删除的move-constructor而不是可用的copy-constructor呢?我在GCC 4.7.2中编译了这个.

struct S
{
    S() = default;
    S(S const &) = default;
    S(S&&) = delete;
};

S f() { return S{}; }

int main()
{
    f();
}
Run Code Online (Sandbox Code Playgroud)

prog.cpp:在函数中‘S f()’:
prog.cpp:8:18:错误:使用已删除的函数‘S::S(S&&)’
prog.cpp:5:5:错误:在此声明

c++ c++11

31
推荐指数
1
解决办法
1025
查看次数

不同类型的三元运算符

下面的代码在g ++ 4.9.2和clang ++ 3.7.0下表现不同.哪一个是正确的?标准中的哪一部分与此相关?谢谢.

#include <iostream>
using namespace std;

struct Base {
  Base() = default;
  Base(const Base&) = default;
  Base(Base&&) = delete;
};

struct Derived : Base {
};

int main() {
  const Base& b = true ? Derived() : Base();
}
Run Code Online (Sandbox Code Playgroud)

g ++接受它并且clang ++给出错误incompatible operand types ('Derived' and 'Base').请参阅下文了解详情.

[hidden]$ g++ -v
Using built-in specs.
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id …
Run Code Online (Sandbox Code Playgroud)

c++ c++11 c++14

17
推荐指数
1
解决办法
2841
查看次数

std :: function不是gcc中的MoveConstructible函数对象

我想要相处std::function.从这里引用可以看出,对std::functionctor的论证应该是可调用的并且可以复制构造.所以这是一个小例子:

#include <iostream>
#include <type_traits>
#include <functional>

class A {
public:
    A(int a = 0): a_(a) {}
    A(const A& rhs): a_(rhs.a_) {}
    A(A&& rhs) = delete;
    void operator() ()
    {
        std::cout << a_ << std::endl;
    }

private:
    int a_;
};

typedef std::function<void()> Function;

int main(int argc, char *argv[])
{
    std::cout << std::boolalpha;
    std::cout << "Copy constructible: "
              << std::is_copy_constructible<A>::value << std::endl;
    std::cout << "Move constructible: "
              << std::is_move_constructible<A>::value << std::endl;
    //Function f = A(); …
Run Code Online (Sandbox Code Playgroud)

c++ gcc c++11

16
推荐指数
1
解决办法
370
查看次数

为什么当T不可移动构造时,std :: optional的move-constructor不会被删除?

根据标准,复制构造函数std::optional<T>:

......除非is_copy_constructible_v<T>是,否则应被定义为删除true.

但是移动构造函数std::optional<T>:

......除非is_move_constructible_v<T>是,否则不得参与超载决议true.

据我了解删除的构造函数,不删除move-constructor的目的std::optional<T>是允许这样的代码:

std::optional<X> o1;
std::optional<X> o2(std::move(o1));
Run Code Online (Sandbox Code Playgroud)

......依靠一些转换序列工作 - o2将由一个A使用a构造的类型的对象构造std::optional<X>&&(如果我错了,请纠正我).

但是对于可能的构造函数std::optional,我很难找到一个可以匹配这个用例的...

为什么移动构造函数std::optional<T>根本不被删除,如果T不是可移动构造的?

c++ optional move-constructor

12
推荐指数
2
解决办法
695
查看次数

转换运算符+转换构造函数=不直观的行为?

我不明白为什么下面的代码打印struct Value而不是int(这意味着转换构造函数转换为Value而不是int).(Visual C++ 2012)

为什么会这样?为什么编译器完全忽略Value(int)构造函数?

#include <iostream>
#include <type_info>

using namespace std;

struct Value { Value(int) { } };

struct Convertible
{
    template<class T>
    operator T() const
    { throw typeid(T).name(); }
};

int main()
{
    try { Value w((Convertible())); }
    catch (char const *s) { cerr << s << endl; }
}
Run Code Online (Sandbox Code Playgroud)

编辑:

更奇怪的是这次(这次只是C++ 11,在GCC 4.7.2上):

#include <iostream>
#include <typeinfo>

using namespace std;

struct Value
{
    Value(Value const …
Run Code Online (Sandbox Code Playgroud)

c++ visual-c++ implicit-conversion

11
推荐指数
1
解决办法
666
查看次数

C++ 11"不可移动"类型

可能重复:
为什么C++ 11删除的函数参与重载解析?

我有两个关于以下C++ 11代码的问题:

#include <iostream>

using namespace std;

struct A {
  A()  { cout << "Default c-tor" << endl; }
  A(const A&)  { cout << "Copy c-tor" << endl; }
  A(A&&) = delete;
};

A f()
{
 A a;
 return a;
}

int main()
{
  A b = f();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我用gcc和clang得到以下编译错误

gcc-4.7.2(g ++ --std = c ++ 11 main.cpp):

main.cpp: In function ‘A f()’:
main.cpp:16:9: error: use of deleted function ‘A::A(A&&)’
main.cpp:8:2: error: declared here
main.cpp: …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang move-semantics c++11

11
推荐指数
1
解决办法
1740
查看次数

为什么删除的移动语义会导致std :: vector出现问题?

在做了一些研究之后,我发现C++ 11的分配器存在缺陷,需要类型可移动/可复制.我确定这是导致这个问题的原因,但我对删除和未声明的移动语义之间的行为感到困惑.

我有以下代码无法在MSVC12和Clang上编译:

#include <vector>

class Copyable
{
public:
   Copyable() = default;

   Copyable(Copyable const& other)
      : m_int(other.m_int)
   {}

   Copyable& operator= (Copyable const& other)
   {
      m_int = other.m_int;
      return *this;
   }

   Copyable(Copyable&&) = delete;
   Copyable& operator= (Copyable&&) = delete;

private:
   int m_int = 100;
};

int main()
{
   std::vector<Copyable> objects;
   objects.push_back(Copyable{});
}
Run Code Online (Sandbox Code Playgroud)

这无法在MSVC上编译:

xmemory0(600):错误C2280:'可复制::可复制(可复制&&)':尝试引用已删除的函数

而对于Clang(现场样本):

new_allocator.h:120:23:错误:调用'Copyable'的已删除构造函数

在这两种情况下,当我删除显式删除的移动构造/分配方法时,代码编译.AFAIK在声明复制赋值/构造方法时,编译器不会隐式声明相应的移动成员.所以它们仍应被有效删除,对吧?当我删除move construct/assign的显式删除时,为什么代码会编译?

一般来说,这个C++ 11缺陷有什么好的解决方法?我不希望我的物体可以移动(但它们是可复制的).

c++ c++11

10
推荐指数
2
解决办法
1095
查看次数

模板构造函数无法选择?

template <typename T>
class A {
public:
    template<class C> A(const A<C>&) {}
    A(A&&) {}
};

void f(A<int>& a)
{
    A<int> b(a);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码不能在g ++/clang ++中编译报告复制构造函数因为用户提供的移动构造函数而被删除(尽管vc ++编译好了).是否有任何标准要求阻止在重载解析期间选择模板构造函数(我知道它不是复制构造函数)?或者是否要求初始化程序与initializee具有相同的类型时,它必须选择复制构造函数?

c++ templates constructor language-lawyer

6
推荐指数
1
解决办法
133
查看次数

直接列表初始化编译成功,但正常的直接初始化失败,为什么?

例如,代码如下:

struct A { A(int); };
struct B { B(A);   };

int main()
{
    B b{{0}}; // OK
    B c({0}); // error
}
Run Code Online (Sandbox Code Playgroud)

错误消息是:

f.cc: In function 'int main()':
f.cc:7:9: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous
  B c({0}); // error

         ^
f.cc:7:9: note: candidates are:
f.cc:2:12: note: B::B(A)
 struct B { B(A);   };
        ^
f.cc:2:8: note: constexpr B::B(const B&)
 struct B { B(A);   };
        ^
f.cc:2:8: note: constexpr B::B(B&&)
Run Code Online (Sandbox Code Playgroud)

c++ initialization overload-resolution

6
推荐指数
1
解决办法
298
查看次数