C++ 单独的allocate()定义会导致;“未定义引用”;C+中的链接错误+;自定义分配器

C++ 单独的allocate()定义会导致;“未定义引用”;C+中的链接错误+;自定义分配器,c++,allocator,C++,Allocator,代码被放在三个文件中:test.hpp、test.cpp和another.cpp 源代码test.hpp: #ifndef TEST_HPP_ #define TEST_HPP_ template<typename T> class Allocator { public: typedef size_t size_type; typedef ptrdiff_t difference_type; typedef T* pointer; typedef c

代码被放在三个文件中:test.hpp、test.cpp和another.cpp

源代码test.hpp:

#ifndef TEST_HPP_
#define TEST_HPP_

template<typename T> class Allocator
{
public:
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    typedef T value_type;
    template<typename O> struct rebind { typedef Allocator<O> other; };

    Allocator() {}
    Allocator(const Allocator& alloc) {}
    template<typename O> Allocator(const Allocator<O>& alloc) {}
    ~Allocator() {}
    pointer address(reference __x) const { return &__x; }
    const_pointer address(const_reference __x) const { return &__x; }
    void construct(pointer p, const T& value) { new ((void *)p) T(value); }
    void destroy(pointer p) { p->~T(); }

    pointer allocate(size_type n, const_pointer pHint = nullptr);// { return nullptr; }
    void deallocate(pointer p, size_type size = 0) {}
    inline size_type max_size() const { return 0; }
};
template<typename T> inline bool operator==(const Allocator<T>&, const Allocator<T>&) { return true; }
template<typename T> inline bool operator!=(const Allocator<T>&, const Allocator<T>&) { return false; }


class String : public std::basic_string<wchar_t, std::char_traits<wchar_t>, Allocator<wchar_t>>
{
    typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, Allocator<wchar_t>> string_type;
public:
    ~String() {}
    String(const wchar_t* value = L"") : string_type(value, Allocator<wchar_t>()) {}
};

#endif /* TEST_HPP_ */
编译将会成功。由于我的自定义分配器::allocate()有点复杂,因此将代码体放入test.hpp头文件中很不方便


有人给我一些建议吗?谢谢。

编译器无法知道您的实现在哪里。由于test.hpp定义了方法,编译器希望在test.cpp中实现。在我看来,这也是构建它的干净方式。但是,如果绝对需要,您可以通过单独编译并以正确的顺序巧妙地链接obj文件来解决这个问题。但是我认为这很肮脏。

我的实际代码可以通过编译作为调试模式和-O1优化发布模式。在-O2和-O3中失败。但是上面显示的简化代码无法通过-O0~-O3的编译。这很难理解。我曾经尝试在allocate()之前添加一个uuu属性uuu((noinline)),但没有效果。我同时使用g++4.8和4.7,结果是一样的。非常感谢!帖子解决了我的问题。关于“由于test.hpp定义了方法,编译器希望实现在test.cpp中”:我认为编译器不会希望实现位于具有特殊名称的cpp文件中。我在另一个.cpp和test.cpp中交换了代码,编译仍然失败,并出现相同的错误。没有正确的顺序可以成功地编译它们。您是将它们单独编译为obj文件,然后手动或一次性将它们链接在一起?
#include <iostream>
#include <string>
#include <ctime>
#include <type_traits>
#include <functional>
#include <cstddef>

#include "test.hpp"
#define MILLIS(time) (clock() - time) * 1000 / CLOCKS_PER_SEC

int main()
{
    String string = L"OK";
    return 0;
}
#include <iostream>
#include <string>
#include <ctime>
#include <type_traits>
#include <functional>
#include <cstddef>
#include "test.hpp"


template<typename T> T* Allocator<T>::allocate(size_t n, const T* pHint)
{
    return nullptr;
}
pointer allocate(size_type n, const_pointer pHint = nullptr) { return nullptr; }