static_assert 与 std::vector 结合使用自定义分配器失败
static_assert fails in conjunction with std::vector with a custom allocator
我正在尝试使用 MSVC 141 编译取自 Chromium 源代码的 PDFium。
该代码是一个自定义分配器。您可以看到可以使用实例化自定义分配器
wchar_t没问题。 wchar_t 显然是算术。
但是,将其传递到向量中会使静态断言失败。
下面的代码给出了一个静态断言,这是我不期望的:
#include <iostream>
#include <type_traits>
#include <vector>
template <typename T>
struct FxAllocAllocator {
public:
static_assert(std::is_arithmetic<T>::value,
"Only numeric types allowed in this partition");
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = size_t;
using difference_type = ptrdiff_t;
template <typename U>
struct rebind {
using other = FxAllocAllocator<U>;
};
FxAllocAllocator() noexcept = default;
FxAllocAllocator(const FxAllocAllocator& other) noexcept = default;
~FxAllocAllocator() = default;
template <typename U>
FxAllocAllocator(const FxAllocAllocator<U>& other) noexcept {}
pointer address(reference x) const noexcept { return &x; }
const_pointer address(const_reference x) const noexcept { return &x; }
pointer allocate(size_type n, const void* hint = 0) {
return static_cast<pointer>(FX_AllocOrDie(n, sizeof(value_type)));
}
void deallocate(pointer p, size_type n) { FX_Free(p); }
size_type max_size() const noexcept {
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
template <typename U, typename... Args>
void construct(U* p, Args&&... args) {
new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...);
}
template <typename U>
void destroy(U* p) {
p->~U();
}
// There's no state, so they are all the same,
bool operator==(const FxAllocAllocator& that) { return true; }
bool operator!=(const FxAllocAllocator& that) { return false; }
};
int main()
{
std::cout << "wchar_t: " << std::is_arithmetic<wchar_t>::value << '\n';
FxAllocAllocator<uint8_t> success;
std::vector<wchar_t, FxAllocAllocator<wchar_t>> fail;
}
这超出了我的能力范围。
到目前为止,我的猜测是 MSVC 编译器的工作方式与 GCC 不同,或者我缺少编译器选项。
我试过 MSVC 141 和 142。C++11 到 c++17。
任何人都可以向我解释为什么这不能编译吗?
似乎 Visual Studio 调试运行时代码在 std::vector
的析构函数中有一个假定迭代器调试的部分。由于可能的版权问题,我无法在此处 post 代码。
我的猜测是调试运行时期望分配器是标准的 Visual C++ 分配器,带有调试信息。如果我错了,有人会纠正我,但这是 static_assert
指向的地方。
您只能构建发布模式,因为发布构建不会调用调试库代码。
但是,如果您希望轻松调试应用程序,您可以:
1) 将迭代器级别设置为 0(_ITERATOR_DEBUG_LEVEL
预处理器符号应为 0)并重建
或
2) 创建另一个配置(称之为 Release With Debug
)并为 Release
复制相同的设置,但应关闭优化。
我正在尝试使用 MSVC 141 编译取自 Chromium 源代码的 PDFium。 该代码是一个自定义分配器。您可以看到可以使用实例化自定义分配器 wchar_t没问题。 wchar_t 显然是算术。 但是,将其传递到向量中会使静态断言失败。 下面的代码给出了一个静态断言,这是我不期望的:
#include <iostream>
#include <type_traits>
#include <vector>
template <typename T>
struct FxAllocAllocator {
public:
static_assert(std::is_arithmetic<T>::value,
"Only numeric types allowed in this partition");
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = size_t;
using difference_type = ptrdiff_t;
template <typename U>
struct rebind {
using other = FxAllocAllocator<U>;
};
FxAllocAllocator() noexcept = default;
FxAllocAllocator(const FxAllocAllocator& other) noexcept = default;
~FxAllocAllocator() = default;
template <typename U>
FxAllocAllocator(const FxAllocAllocator<U>& other) noexcept {}
pointer address(reference x) const noexcept { return &x; }
const_pointer address(const_reference x) const noexcept { return &x; }
pointer allocate(size_type n, const void* hint = 0) {
return static_cast<pointer>(FX_AllocOrDie(n, sizeof(value_type)));
}
void deallocate(pointer p, size_type n) { FX_Free(p); }
size_type max_size() const noexcept {
return std::numeric_limits<size_type>::max() / sizeof(value_type);
}
template <typename U, typename... Args>
void construct(U* p, Args&&... args) {
new (reinterpret_cast<void*>(p)) U(std::forward<Args>(args)...);
}
template <typename U>
void destroy(U* p) {
p->~U();
}
// There's no state, so they are all the same,
bool operator==(const FxAllocAllocator& that) { return true; }
bool operator!=(const FxAllocAllocator& that) { return false; }
};
int main()
{
std::cout << "wchar_t: " << std::is_arithmetic<wchar_t>::value << '\n';
FxAllocAllocator<uint8_t> success;
std::vector<wchar_t, FxAllocAllocator<wchar_t>> fail;
}
这超出了我的能力范围。 到目前为止,我的猜测是 MSVC 编译器的工作方式与 GCC 不同,或者我缺少编译器选项。 我试过 MSVC 141 和 142。C++11 到 c++17。 任何人都可以向我解释为什么这不能编译吗?
似乎 Visual Studio 调试运行时代码在 std::vector
的析构函数中有一个假定迭代器调试的部分。由于可能的版权问题,我无法在此处 post 代码。
我的猜测是调试运行时期望分配器是标准的 Visual C++ 分配器,带有调试信息。如果我错了,有人会纠正我,但这是 static_assert
指向的地方。
您只能构建发布模式,因为发布构建不会调用调试库代码。
但是,如果您希望轻松调试应用程序,您可以:
1) 将迭代器级别设置为 0(_ITERATOR_DEBUG_LEVEL
预处理器符号应为 0)并重建
或
2) 创建另一个配置(称之为 Release With Debug
)并为 Release
复制相同的设置,但应关闭优化。