专业 std::make_shared
Specializing std::make_shared
我有一个具有严格对齐要求(由于使用了 AVX 操作)的类型,它大于平台默认对齐方式。
为了更简单地使用这个 class,我想专门化 std::make_shared
以始终为这种类型使用合适的分配器。
像这样:
namespace std{
template<class... Args> inline
auto make_shared<X, Args...>(Args&&... args){
return std::allocate_shared(allocator_type<X, 32>, std::forward<Args>(args)...);
}
}
我的问题是,标准允许这样做吗?它会按预期工作吗?
来自 N4140 [namespace.std]/1(强调我的):
The behavior of a C++program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization
for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
由于您要添加依赖于用户定义类型的模板特化,因此这是 std
命名空间的有效扩展。
但是,正如@dyp 所指出的,您不能部分特化函数模板。您最好的选择是显式指定 X
构造函数的参数(失去完美转发),或者只编写一个 make_shared_x
函数(失去一致性)。
这就是我最终得到一个不涉及大量样板的通用解决方案的方法:
namespace xtd{
template< typename T, std::size_t align = std::alignment_of<T>::value, typename... Args >
std::shared_ptr<T> make_shared(Args&&... args){
// Platform specific knowledge.
#if defined(_WIN64) || defined(_WIN32)
#if defined(_WIN64)
const std::size_t default_alignment = 16;
#else
const std::size_t default_alignment = 8;
#endif
#else
#error "Only windows for now"
#endif
if (align > default_alignment) {
typedef aligned_allocator<T, align> alloc_type;
return std::allocate_shared<T, alloc_type>(alloc_type(), std::forward<Args>(args)...);
}
else {
return std::make_shared<T>(std::forward<Args>(args)...);
}
}
}
然后我找到搜索并替换 std::make_shared
为 xtd::make_shared
:)
我希望这符合标准...
我有一个具有严格对齐要求(由于使用了 AVX 操作)的类型,它大于平台默认对齐方式。
为了更简单地使用这个 class,我想专门化 std::make_shared
以始终为这种类型使用合适的分配器。
像这样:
namespace std{
template<class... Args> inline
auto make_shared<X, Args...>(Args&&... args){
return std::allocate_shared(allocator_type<X, 32>, std::forward<Args>(args)...);
}
}
我的问题是,标准允许这样做吗?它会按预期工作吗?
来自 N4140 [namespace.std]/1(强调我的):
The behavior of a C++program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
由于您要添加依赖于用户定义类型的模板特化,因此这是 std
命名空间的有效扩展。
但是,正如@dyp 所指出的,您不能部分特化函数模板。您最好的选择是显式指定 X
构造函数的参数(失去完美转发),或者只编写一个 make_shared_x
函数(失去一致性)。
这就是我最终得到一个不涉及大量样板的通用解决方案的方法:
namespace xtd{
template< typename T, std::size_t align = std::alignment_of<T>::value, typename... Args >
std::shared_ptr<T> make_shared(Args&&... args){
// Platform specific knowledge.
#if defined(_WIN64) || defined(_WIN32)
#if defined(_WIN64)
const std::size_t default_alignment = 16;
#else
const std::size_t default_alignment = 8;
#endif
#else
#error "Only windows for now"
#endif
if (align > default_alignment) {
typedef aligned_allocator<T, align> alloc_type;
return std::allocate_shared<T, alloc_type>(alloc_type(), std::forward<Args>(args)...);
}
else {
return std::make_shared<T>(std::forward<Args>(args)...);
}
}
}
然后我找到搜索并替换 std::make_shared
为 xtd::make_shared
:)
我希望这符合标准...