我有一个删除了移动构造函数的类,当我尝试在MSVC中调用std :: vector :: push_back()时(v.15.8.7 Visual C++ 2017)我收到错误消息说我正在尝试访问已删除的移动构造函数.但是,如果我定义了移动构造函数,则代码会编译,但永远不会调用移动构造函数.这两个版本在gcc(v.5.4)上按预期编译和运行.
这是一个简化的例子:
#include <iostream>
#include <vector>
struct A
{
public:
A() { std::cout << "ctor-dflt" << std::endl; }
A(const A&) { std::cout << "ctor-copy" << std::endl; }
A& operator=(const A&) { std::cout << "asgn-copy" << std::endl; return *this; }
A(A&&) = delete;
A& operator=(A&& other) = delete;
~A() { std::cout << "dtor" << std::endl; }
};
int main()
{
std::vector<A> v{};
A a;
v.push_back(a);
}
Run Code Online (Sandbox Code Playgroud)
在Visual Studio上编译时会出现以下错误:
error C2280: 'A::A(A &&)': attempting to …Run Code Online (Sandbox Code Playgroud) 我是游戏开发的新手,也是c ++的新手,但我已经开始开发一款小型的Arkanoid游戏了.我以前运行它,但在重构(引入ArkanoidGame类)后它没有编译,我无法弄清楚为什么.
我得到的错误是:
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\main.cpp(14): error C2280:
'ArkanoidGame::ArkanoidGame(void)' : attempting to reference a deleted function
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\arkanoidgame.h(25) :
compiler has generated 'ArkanoidGame::ArkanoidGame' here
Run Code Online (Sandbox Code Playgroud)
我根本不明白这意味着什么,不知道如何解决它.
我已经包含了有问题的课程:
Main.cpp的:
#include "ArkanoidGame.h"
int main() {
ArkanoidGame game;
game.init(800, 600);
while (game.isRunning()) {
game.checkInput();
game.checkCollisions();
game.draw();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Arkanoid.h:
#include "Ball.h"
#include "Pad.h"
#include <SFML/Graphics.hpp>
#include <stdarg.h>
#include <memory>
class ArkanoidGame
{
private:
bool running;
public:
void ArkanoidGame::init(int, int);
bool ArkanoidGame::isRunning();
void ArkanoidGame::checkCollisions();
void ArkanoidGame::checkInput();
void ArkanoidGame::update();
void ArkanoidGame::draw();
sf::RenderWindow* window;
Pad pad;
Ball ball; …Run Code Online (Sandbox Code Playgroud) 考虑这两个可能的类定义:
图表A:
struct A
{
A() = delete;
};
Run Code Online (Sandbox Code Playgroud)
图表A':
struct A
{
A() noexcept = delete;
}
Run Code Online (Sandbox Code Playgroud)
声明删除的函数是否有任何意义noexcept?
这两行奇怪的代码是什么意思?
thread_guard(thread_guard const&) = delete;
thread_guard& operator=(thread_guard const&) = delete;
Run Code Online (Sandbox Code Playgroud) 这段代码不能用gcc 4.7.0编译:
class Base
{
public:
Base(const Base&) = delete;
};
class Derived : Base
{
public:
Derived(int i) : m_i(i) {}
int m_i;
};
Run Code Online (Sandbox Code Playgroud)
错误是:
c.cpp: In constructor ‘Derived::Derived(int)’:
c.cpp:10:24: error: no matching function for call to ‘Base::Base()’
c.cpp:10:24: note: candidate is:
c.cpp:4:2: note: Base::Base(const Base&) <deleted>
c.cpp:4:2: note: candidate expects 1 argument, 0 provided
Run Code Online (Sandbox Code Playgroud)
换句话说,编译器不会为基类生成默认构造函数,而是尝试将已删除的复制构造函数作为唯一可用的重载调用.
这是正常的行为吗?
struct A
{
A(int x)
: n(x)
{}
A(A&&)
{}
A& operator =(A&&)
{
return *this;
}
int n;
};
int main()
{
A a(1), b(2);
a = b;
if (2 == a.n)
{
// It SHOULD go here!
}
}
Run Code Online (Sandbox Code Playgroud)
根据C++标准12.8.7:
如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除;
和12.8.18
如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制赋值运算符被定义为已删除;
该语句a = b;应该触发编译器错误.但是,我的编译器(VC++ 2013 RC)接受它并调用隐式定义的复制赋值.
这是编译器的错误吗?
更新:
我已将此问题作为错误提交给microsoft.
c++ compiler-construction copy-constructor deleted-functions c++11
我不确定以下代码是否符合c ++ 11标准,并且应该在不同的实现中具有相同的行为:
#include <cstddef>
struct Foo{
template <std::size_t N>
constexpr Foo( const char ( &other )[N] )
{}
template <class T>
constexpr Foo( const T* const& other ) = delete;
};
struct Bar {
Foo a;
int b;
};
int main() {
Bar bar{ "Hello",5};
}
Run Code Online (Sandbox Code Playgroud)
一般的想法是允许构造一个字符串文字和一个std::string(这里没有显示),但不是指针const char,这有点棘手(在这个问题中讨论).
较新版本的g ++(> = 6.0)和几乎所有clang ++版本(> = 3.4)似乎编译得很好,但是例如 g++-4.8 -std=c++11 main.cpp我得到以下错误:
main.cpp: In function ‘int main()’:
main.cpp:17:27: error: use of deleted function ‘constexpr Foo::Foo(const T* …Run Code Online (Sandbox Code Playgroud) 我正在使用 g++ 5.1.0 编译以下 C++14 程序test.cpp:
#include <memory>
class Factor {
public:
Factor(const Factor&) = default;
Factor(Factor&&) = default;
Factor& operator=(const Factor&) = default;
Factor& operator=(Factor&&) = default;
Factor(int data) {
_data = std::make_unique<int>(data);
}
int* data() const { return _data.get(); }
private:
std::unique_ptr<int> _data;
};
class Node {
public:
Node(const Node& other) : _factor(other._factor) {
}
private:
Factor _factor;
};
int main(int argc, char **argv) {
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译时,出现以下错误:
test.cpp: In copy constructor ‘Node::Node(const Node&)’:
test.cpp:19:52: error: use …Run Code Online (Sandbox Code Playgroud) 说我有这个结构:
struct F
{
int& ref; // reference member
const int c; // const member
// F::F() is implicitly defined as deleted
};
Run Code Online (Sandbox Code Playgroud)
那是来自cppreference.据我从文档中理解,构造函数F被认为是删除的,因为它有一个引用变量,它什么都没引用.因此,不能F像这样声明类型的变量:F variableName;因为会出现错误,例如:struct中的未初始化的引用成员F.
我理解这一点但是我不明白如果你甚至不能声明它的类型的变量这样的结构会有什么好处.这种数据类型在某些特定情况下是否有用?
有一个包含POD的结构,默认构造函数已删除。尝试对struct实例进行汇总初始化时,使用编译时会在g ++ 9.1中导致编译错误-std=c++2a。相同的代码可以使用编译-std=c++17。
struct S
{
int a;
S() = delete;
};
int main()
{
S s {.a = 0};
}
Run Code Online (Sandbox Code Playgroud) c++ ×10
c++11 ×4
gcc ×2
c++17 ×1
c++20 ×1
constructor ×1
noexcept ×1
overloading ×1
pointers ×1
push-back ×1
templates ×1
visual-c++ ×1