gpt4 book ai didi

c++ - 外部模板类 std::container of movable objects

转载 作者:搜寻专家 更新时间:2023-10-31 00:36:09 27 4
gpt4 key购买 nike

我想将新的 C++11 功能“外部模板类”与可移动对象的 STL 容器(不可复制)一起使用,并遇到编译器错误。

例子:MyFile.hpp

#pragma once

#include <cstdio>

class MyFile
{
std::FILE * handle;

public:
MyFile(const char * filename);

~MyFile();

MyFile(MyFile && that);

MyFile & operator=(MyFile && that);

MyFile(const MyFile&) = delete;
void operator=(const MyFile&) = delete;

std::FILE const * getFile() const;
};

MyFile.cpp:

#include "MyFile.hpp"

#include <iostream>

MyFile::MyFile(const char * filename)
: handle{nullptr}
{
if (!(handle = fopen(filename, "r")))
throw std::runtime_error("blah blah blah");
}

MyFile::~MyFile()
{
std::cout << "File::~File()" << std::endl;
if (handle)
fclose(handle);
}

MyFile::MyFile(MyFile && that)
: handle{nullptr}
{
*this = std::move(that);
}

MyFile & MyFile::operator =(MyFile && that)
{
std::swap(handle, that.handle);
return *this;
}

const std::FILE * MyFile::getFile() const
{
return handle;
}

FileDeque.hpp:

#pragma once

#include <deque>

#include "MyFile.hpp"

extern template class std::deque<MyFile>;
using FileDeque = std::deque<MyFile>;

FileDeque.cpp:

#include "FileDeque.hpp"

template class std::deque<MyFile>;

和测试程序: #包括

using namespace std;

#include "MyFile.hpp"
#include "FileDeque.hpp"

int main()
{
cout << "Hello World!" << endl;

{
FileDeque files;
files.emplace_back("C:/eula.1028.txt");
files.emplace_back("C:/eula.1031.txt");
files.emplace_back("C:/eula.2052.txt");
}

return 0;
}

使用 Visual Studio 2013 时出现以下错误:

D:\WinPrograms\Microsoft Visual Studio 12.0\VC\INCLUDE\deque(1714) : error C2280: 'MyFile::MyFile(const MyFile &)' : attempting to reference a deleted function

d:\devel\unique_ptr3\MyFile.hpp(18) : see declaration of 'MyFile::MyFile'

D:\WinPrograms\Microsoft Visual Studio 12.0\VC\INCLUDE\deque(1682) : while compiling class template member function 'void std::deque>::_Insert_n(std::_Deque_const_iterator>>,unsigned int,const MyFile &)' with [ _Ty=MyFile ]

D:\WinPrograms\Microsoft Visual Studio 12.0\VC\INCLUDE\deque(1510) : see reference to function template instantiation 'void std::deque>::_Insert_n(std::_Deque_const_iterator>>,unsigned int,const MyFile &)' being compiled with [ _Ty=MyFile ]

d:\devel\unique_ptr3\FileDeque.hpp(7) : see reference to class template instantiation 'std::deque>' being compiled with [ _Ty=MyFile ]

Generating Code...

很明显,编译器试图实例化使用对象复制的 std::deque>::_Insert_n 函数,但为什么呢?

如果在 main.cpp 中直接使用 std::deque,则不会出现错误:

#include <iostream>

#include <deque>

using namespace std;

#include "MyFile.hpp"

using FileDeque = std::deque<MyFile>;

int main()
{
cout << "Hello World!" << endl;

{
FileDeque files;
files.emplace_back("C:/eula.1028.txt");
files.emplace_back("C:/eula.1031.txt");
files.emplace_back("C:/eula.2052.txt");
}

return 0;
}

还尝试使用 clang 和 gcc 并得到类似的错误。

所以我的问题:

  1. 是否可以让编译器不实例化容器类的可移动对象?为什么编译器会尝试实例化需要复制支持的方法?
  2. 我想做错事吗?

最佳答案

C++11 [temp.explicit]/8 状态:

An explicit instantiation that names a class template specialization is also an explicit instantiation of the same kind (declaration or definition) of each of its members (not including members inherited from base classes) that has not been previously explicitly specialized in the translation unit containing the explicit instantiation, except as described below.

由于 std::deque<foo> 的一些成员需要可复制类型 foo - 至少,复制构造函数 - 实例化它们是错误的。这是您观察到的错误的原因。

解决方法是仅显式实例化您的程序使用的格式良好的成员,例如:

// in FileDeque.hpp:
// Uncomment this to get linker errors suggesting
// other members to explicitly instantiate:
// extern template class std::deque<MyFile>;
extern template std::deque<MyFile>::deque();
extern template std::deque<MyFile>::~deque();
extern template auto std::deque<MyFile>::begin() -> iterator;
extern template auto std::deque<MyFile>::end() -> iterator;
// ...

// in FileDeque.cpp:
template std::deque<MyFile>::deque();
template std::deque<MyFile>::~deque();
template auto std::deque<MyFile>::begin() -> iterator;
template auto std::deque<MyFile>::end() -> iterator;
// ...

关于c++ - 外部模板类 std::container of movable objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22381685/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com