编译代码时出现意外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 toTestClass::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 toInformation::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);

http://en.cppreference.com/w/cpp/language/type_alias