error: static assertion failed: result type must be constructible from value type of input range 127 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
问题复现
- cmake 3.16
- gcc 9.4.0
- ubuntu 20.04
main.cpp:
#include <iostream>
#include <vector>
#include <memory>
struct Test {
float x;
Test() = default;
Test(const Test&) = default;
Test& operator=(const Test&) = default;
Test(Test&&) = default;
Test& operator=(Test&&) = default;
};
class MyClass {
public:
MyClass(int count) : count(count) {}
// MyClass(const MyClass&) = delete;
~MyClass() = default;
private:
int count; // 基本类型成员变量
std::vector<std::unique_ptr<Test>> vec;
};
int main()
{
auto obj = MyClass(10);
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(test_unique)
set(CMAKE_CXX_STANDARD 14)
add_executable(main main.cpp)
编译错误
mkdir build
cd build
cmake ..
make
In file included from /usr/include/c++/9/vector:66,
from /home/huangruixin/Downloads/test_unique/main.cpp:2:
/usr/include/c++/9/bits/stl_uninitialized.h: In instantiation of ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<Test>*, std::vector<std::unique_ptr<Test> > >; _ForwardIterator = std::unique_ptr<Test>*]’:
/usr/include/c++/9/bits/stl_uninitialized.h:307:37: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::unique_ptr<Test>*, std::vector<std::unique_ptr<Test> > >; _ForwardIterator = std::unique_ptr<Test>*; _Tp = std::unique_ptr<Test>]’
/usr/include/c++/9/bits/stl_vector.h:555:31: required from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::unique_ptr<Test>; _Alloc = std::allocator<std::unique_ptr<Test> >]’
/home/huangruixin/Downloads/test_unique/main.cpp:14:7: required from here
/usr/include/c++/9/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range
127 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
| ^~~~~
make[2]: *** [CMakeFiles/main.dir/build.make:63: CMakeFiles/main.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
问题分析
铁出来的 error log 前两行是这样的:
In file included from /usr/include/c++/9/vector:66,
from /home/huangruixin/Downloads/test_unique/main.cpp:2:
从这里面根本看不出来任何的信息,main.cpp
的第二行是 #include <vector>
,这个信息对于我们来说没有任何帮助。
从后面的 log 还是能看出来和 std::vector<std::unique_ptr<Test>>
有关,但是具体是什么问题呢?
再分析后面的 log,发现调用的链路是这样的:
main.cpp:14:7 -> stl_vector.h:555:31 -> stl_uninitialized.h:307:37 -> stl_uninitialized.h:127:72
重点就是 main.cpp:14:7
根本没有提供任何有用的信息,这个位置就是类的声明而已。
最终偶然发现是调用了编译器生成的 MyClass
的拷贝构造函数,里面操作了 std::vector<std::unique_ptr<Test>>
,这个就是问题的根源。
解决方案
- 删除拷贝构造函数和拷贝赋值函数
- 自定义拷贝构造函数和拷贝赋值函数