如何解决类型依赖? (X 使用未定义的 class Y)
How to unravel type dependency? (X uses undefined class Y)
我正在尝试为我的委托类型实现简单的快速内存管理,但遇到了我自己无法解决的循环依赖。
// Size of single bucket of delegates
static constexpr size_t _alloc_buffer_bucket_size = 128;
template <typename TFunc, typename... Args>
struct bucket;
template <typename TFunc, typename... Args>
class Delegate final : public IDelegate
{
. . .
static void* operator new (size_t size)
{
auto bckt = _current_bucket; // gives compilation error here
}
private:
// Size of single bucket of delegates
static constexpr size_t _alloc_buffer_bucket_size = 128;
struct bucket
{
// stores currently occupied slots in bucket.
size_t allocated_slots = 0;
// when this bucket is filling with values, this
size_t current_slot = 0;
std::array<Delegate<TFunc, Args...>, _alloc_buffer_bucket_size> slots = {};
};
// Vector of buckets.
inline static std::vector<bucket*> _alloc_buffer = { new bucket(), };
// This is a pointer to currently filling bucket. New delegates are added here
// by delegate allocator.
// When this bucket reaches _alloc_buffer_bucket_size of items, this pointer is
// replaced with either newly allocated bucket or existing and empty bucket.
inline static bucket* _current_bucket = &(_alloc_buffer[0]);
};
这给了我“'Delegate<void (*)(void)>::bucket::slots' uses undefined class 'std::array<Delegate<void (*)(void)>,128>'
”。
我怎样才能打破这种循环依赖?我尝试使用更多指针,将存储桶移出委托范围,但此错误仍然存在。
通过将 bucket
结构的定义移动到 Delegate
的范围之外,并将 _alloc_buffer
和 _current_bucket
变量分配到 class 之外作用域,我们就可以实现编译。我能够这样编译它:
// Size of single bucket of delegates
static constexpr std::size_t _alloc_buffer_bucket_size = 128;
template <typename TFunc, typename... Args>
struct bucket;
template <typename TFunc, typename... Args>
class Delegate final : public IDelegate
{
public:
Delegate() = default;
static void* operator new (std::size_t size)
{
auto bckt = _current_bucket; // gives compilation error here
return nullptr; // added to get rid of the error
}
private:
// Vector of buckets.
static std::vector<bucket<TFunc, Args...>*> _alloc_buffer;
// This is a pointer to currently filling bucket. New delegates are added here
// by delegate allocator.
// When this bucket reaches _alloc_buffer_bucket_size of items, this pointer is
// replaced with either newly allocated bucket or existing and empty bucket.
static bucket<TFunc, Args...>* _current_bucket;
};
template <typename TFunc, typename... Args>
struct bucket
{
// stores currently occupied slots in bucket.
std::size_t allocated_slots = 0;
// when this bucket is filling with values, this
std::size_t current_slot = 0;
std::array<Delegate<TFunc, Args...>, _alloc_buffer_bucket_size> slots = {};
};
template <typename TFunc, typename... Args>
std::vector<bucket<TFunc, Args...>*> Delegate<TFunc, Args...>::_alloc_buffer = { new bucket<TFunc, Args...>(), };
template <typename TFunc, typename... Args>
bucket<TFunc, Args...>* Delegate<TFunc, Args...>::_current_bucket = &(_alloc_buffer[0]);
通过拆分静态变量的声明和定义,拆分出bucket类型,Delegate
class在我们去实际使用的时候定义好了。在此处查看实际效果:https://godbolt.org/z/bx7hh1av9
编辑:在 MSVC 和 Clang 上测试了这个最小样本。
我正在尝试为我的委托类型实现简单的快速内存管理,但遇到了我自己无法解决的循环依赖。
// Size of single bucket of delegates
static constexpr size_t _alloc_buffer_bucket_size = 128;
template <typename TFunc, typename... Args>
struct bucket;
template <typename TFunc, typename... Args>
class Delegate final : public IDelegate
{
. . .
static void* operator new (size_t size)
{
auto bckt = _current_bucket; // gives compilation error here
}
private:
// Size of single bucket of delegates
static constexpr size_t _alloc_buffer_bucket_size = 128;
struct bucket
{
// stores currently occupied slots in bucket.
size_t allocated_slots = 0;
// when this bucket is filling with values, this
size_t current_slot = 0;
std::array<Delegate<TFunc, Args...>, _alloc_buffer_bucket_size> slots = {};
};
// Vector of buckets.
inline static std::vector<bucket*> _alloc_buffer = { new bucket(), };
// This is a pointer to currently filling bucket. New delegates are added here
// by delegate allocator.
// When this bucket reaches _alloc_buffer_bucket_size of items, this pointer is
// replaced with either newly allocated bucket or existing and empty bucket.
inline static bucket* _current_bucket = &(_alloc_buffer[0]);
};
这给了我“'Delegate<void (*)(void)>::bucket::slots' uses undefined class 'std::array<Delegate<void (*)(void)>,128>'
”。
我怎样才能打破这种循环依赖?我尝试使用更多指针,将存储桶移出委托范围,但此错误仍然存在。
通过将 bucket
结构的定义移动到 Delegate
的范围之外,并将 _alloc_buffer
和 _current_bucket
变量分配到 class 之外作用域,我们就可以实现编译。我能够这样编译它:
// Size of single bucket of delegates
static constexpr std::size_t _alloc_buffer_bucket_size = 128;
template <typename TFunc, typename... Args>
struct bucket;
template <typename TFunc, typename... Args>
class Delegate final : public IDelegate
{
public:
Delegate() = default;
static void* operator new (std::size_t size)
{
auto bckt = _current_bucket; // gives compilation error here
return nullptr; // added to get rid of the error
}
private:
// Vector of buckets.
static std::vector<bucket<TFunc, Args...>*> _alloc_buffer;
// This is a pointer to currently filling bucket. New delegates are added here
// by delegate allocator.
// When this bucket reaches _alloc_buffer_bucket_size of items, this pointer is
// replaced with either newly allocated bucket or existing and empty bucket.
static bucket<TFunc, Args...>* _current_bucket;
};
template <typename TFunc, typename... Args>
struct bucket
{
// stores currently occupied slots in bucket.
std::size_t allocated_slots = 0;
// when this bucket is filling with values, this
std::size_t current_slot = 0;
std::array<Delegate<TFunc, Args...>, _alloc_buffer_bucket_size> slots = {};
};
template <typename TFunc, typename... Args>
std::vector<bucket<TFunc, Args...>*> Delegate<TFunc, Args...>::_alloc_buffer = { new bucket<TFunc, Args...>(), };
template <typename TFunc, typename... Args>
bucket<TFunc, Args...>* Delegate<TFunc, Args...>::_current_bucket = &(_alloc_buffer[0]);
通过拆分静态变量的声明和定义,拆分出bucket类型,Delegate
class在我们去实际使用的时候定义好了。在此处查看实际效果:https://godbolt.org/z/bx7hh1av9
编辑:在 MSVC 和 Clang 上测试了这个最小样本。