簡體   English   中英

專攻std :: make_shared

[英]Specializing std::make_shared

我有一個嚴格對齊要求的類型(由於使用了AVX操作),它大於平台默認對齊。

為了使這個類的使用更簡單,我想專門化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(強調我的):

如果C ++程序向命名空間std或命名空間std中的命名空間添加聲明或定義,則它是未定義的,除非另有說明。 只有當聲明取決於用戶定義的類型並且特化符合原始模板的標准庫要求且未明確禁止時, 程序才可以將任何標准庫模板的模板特化添加到命名空間std

由於您要添加依賴於用戶定義類型的模板特化,因此這是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_sharedxtd::make_shared :)

我希望這會符合標准......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM