编译代码时出现意外std::allocator如何解决?
How to solve an unexpect std::allocator when compile code?
我定义了一个 class 的构造函数如下:
struct TestClass
{
TestClass(std::uint8_t, std::vector<Type>)
{
//...
}
};
然后我想用googletest做一个单元测试,在尝试构造TestClass的实例时出现编译错误,如下:
TEST(name1,name2)
{
//...
Type element;
std::vector<Type> lst{element};
TestClass instance(0, lst);
//...
}
gnu 编译器报告:
"In function name1_name2_Test::TestBody()':test.cpp:(.text+0x165d): undefined reference to
TestClass::TestClass(signed char, std::vector< Type, std::allocator< Type>)'
collect2: error: ld returned 1 exit status"
以下是我的环境:
g++ version: 5.3.0
google test version: 1.7.0
the compile command: g++ -D_GLIBCXX_USE_CXX11_ABI=0 test.cpp -std=c++14 -lboost_system -lgtest -lgtest_main -lpthread
你遇到过类似的问题吗?请给我一些建议,谢谢。
以下代码可能导致上述错误:
#include <gtest/gtest.h>
struct Element
{
Element(const std::vector<std::uint8_t>& element) : element_(element){}
std::vector<std::uint8_t> element_;
};
using ElementList = std::vector<Element>;
struct Information
{
Information(std::uint8_t, ElementList) {}
std::int8_t number_;
ElementList eleLst_;
};
TEST(name1,name2)
{
std::uint8_t number = 0;
std::vector<std::uint8_t> vec{1,2,3,4};
Element elem(vec);
ElementList lst{elem};
Information info(std::int8_t(0), lst); //false
}
GTEST_API_ int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
编译信息如下:
/tmp/ccUzsTfz.o: In function name1_name2_Test::TestBody()':
test.cpp:(.text+0x130): undefined reference to
Information::Information(unsigned char, std::vector< Element, std::allocator< Element > >)'
collect2: error: ld returned 1 exit status
您的签名是:
struct TestClass
{
TestClass(std::uint8_t, std::vector<Type>)
{
//...
}
};
LINKER 查找:
TestClass::TestClass(signed char, std::vector< Type>, std::allocator< Type>);
您的 TestClass 构造函数定义不包含分配器参数!
这就是为什么没有包含分配器参数的实例化函数,因此链接器找不到它。
编辑:更多参考资料
http://www.cplusplus.com/doc/tutorial/classes/ // 基础
https://isocpp.org/wiki/faq/ctors // 很高兴知道
编辑:有一些误解
TestClass(signed char, std::vector<Type>)
因为构造函数就足够了,如果您使用 "Type"..
类型的标准分配器
参见:
http://de.cppreference.com/w/cpp/container/vector
这是 class:
的签名
template<
class T,
class Allocator = std::allocator<T>
> class vector;
可以看到,它有一个Allocator的默认模板参数赋值,就是std::allocator.
这样,你只需要在模板参数列表中指定一个分配器,如果你有一个自定义分配器,即:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
struct Type {};
template <typename T>
class MyBatchAllocator {
};
template <typename TAllocator = std::allocator<Type>>
class TestClass {
public:
TestClass(signed char, const std::vector<Type, TAllocator>&) {
// ...
}
};
int main()
{
// main.cpp
Type element;
std::vector<Type, MyBatchAllocator<Type>> lst({ element });
TestClass<MyBatchAllocator<Type>> tc(0, lst);
}
否则,如果您使用标准分配器,请使用:
int main() {
Type element;
std::vector<Type> lst2({ element });
TestClass<> tc2(0, lst2);
// Yes, if TestClass is a template with a single
// defaulted template parameter the empty <> are required.
}
附录
如果您想更轻松地使用这些模板,可以使用别名:
using DefaultTestClass = TestClass<>;
并这样称呼它:
DefaultTestClass tc3(0, lst2);
我定义了一个 class 的构造函数如下:
struct TestClass
{
TestClass(std::uint8_t, std::vector<Type>)
{
//...
}
};
然后我想用googletest做一个单元测试,在尝试构造TestClass的实例时出现编译错误,如下:
TEST(name1,name2)
{
//...
Type element;
std::vector<Type> lst{element};
TestClass instance(0, lst);
//...
}
gnu 编译器报告:
"In function
name1_name2_Test::TestBody()':test.cpp:(.text+0x165d): undefined reference to
TestClass::TestClass(signed char, std::vector< Type, std::allocator< Type>)' collect2: error: ld returned 1 exit status"
以下是我的环境:
g++ version: 5.3.0
google test version: 1.7.0
the compile command: g++ -D_GLIBCXX_USE_CXX11_ABI=0 test.cpp -std=c++14 -lboost_system -lgtest -lgtest_main -lpthread
你遇到过类似的问题吗?请给我一些建议,谢谢。
以下代码可能导致上述错误:
#include <gtest/gtest.h>
struct Element
{
Element(const std::vector<std::uint8_t>& element) : element_(element){}
std::vector<std::uint8_t> element_;
};
using ElementList = std::vector<Element>;
struct Information
{
Information(std::uint8_t, ElementList) {}
std::int8_t number_;
ElementList eleLst_;
};
TEST(name1,name2)
{
std::uint8_t number = 0;
std::vector<std::uint8_t> vec{1,2,3,4};
Element elem(vec);
ElementList lst{elem};
Information info(std::int8_t(0), lst); //false
}
GTEST_API_ int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
编译信息如下:
/tmp/ccUzsTfz.o: In function
name1_name2_Test::TestBody()': test.cpp:(.text+0x130): undefined reference to
Information::Information(unsigned char, std::vector< Element, std::allocator< Element > >)'
collect2: error: ld returned 1 exit status
您的签名是:
struct TestClass
{
TestClass(std::uint8_t, std::vector<Type>)
{
//...
}
};
LINKER 查找:
TestClass::TestClass(signed char, std::vector< Type>, std::allocator< Type>);
您的 TestClass 构造函数定义不包含分配器参数!
这就是为什么没有包含分配器参数的实例化函数,因此链接器找不到它。
编辑:更多参考资料
http://www.cplusplus.com/doc/tutorial/classes/ // 基础
https://isocpp.org/wiki/faq/ctors // 很高兴知道
编辑:有一些误解
TestClass(signed char, std::vector<Type>)
因为构造函数就足够了,如果您使用 "Type"..
类型的标准分配器参见: http://de.cppreference.com/w/cpp/container/vector
这是 class:
的签名template<
class T,
class Allocator = std::allocator<T>
> class vector;
可以看到,它有一个Allocator的默认模板参数赋值,就是std::allocator.
这样,你只需要在模板参数列表中指定一个分配器,如果你有一个自定义分配器,即:
#include <iostream>
#include <string>
#include <vector>
#include <memory>
struct Type {};
template <typename T>
class MyBatchAllocator {
};
template <typename TAllocator = std::allocator<Type>>
class TestClass {
public:
TestClass(signed char, const std::vector<Type, TAllocator>&) {
// ...
}
};
int main()
{
// main.cpp
Type element;
std::vector<Type, MyBatchAllocator<Type>> lst({ element });
TestClass<MyBatchAllocator<Type>> tc(0, lst);
}
否则,如果您使用标准分配器,请使用:
int main() {
Type element;
std::vector<Type> lst2({ element });
TestClass<> tc2(0, lst2);
// Yes, if TestClass is a template with a single
// defaulted template parameter the empty <> are required.
}
附录
如果您想更轻松地使用这些模板,可以使用别名:
using DefaultTestClass = TestClass<>;
并这样称呼它:
DefaultTestClass tc3(0, lst2);