2014-09-18 86 views
3

我最近用一些使用SSE的Vector/Matrix類替換了一些,並且現在確保內存正確對齊。自定義std :: allocator替換運算符的新類

按照this question的答案,我已經替換了operator new/delete以獲取需要它的類,並開始使用自定義分配器來使用STL容器 - 但是,似乎有一些衝突這兩個:

爲了開始,我簡單地複製並粘貼了here的樣本分配器類,當我將它用於沒有自定義新/刪除的問題類型的std :: vector時,它編譯得很好,但是當我替換這些函數時,我從構造函數()中得到一個錯誤「沒有匹配'operator new'的匹配函數」,

void construct(pointer p, const T& t) { new(p) T(t); } 

我想我已經取代了「通常」的新的事實,以某種方式模糊放置新?但是,由於我不能寫出自己的貼片,所以我不確定要做什麼......我是新的(NPI)整個定製內存分配的東西,所以任何建議都會非常感謝!我正在Linux上使用Clang v3.4(或gcc 4.1.2)編譯;不使用C++ 11。

非常感謝。

回答

4

的規範allocator::construct電話::new((void *)p) T(val)

通過省略::,你讓名稱查找下手的T,在那裏發現了類作用域類作用域operator new,在沒有進行任何進一步的(name lookup站即使在某個封閉範圍內存在更好的候選者,也可以找到任何匹配名稱的第一個作用域)

(如果用戶潛入全局幾乎放置的新重載, void指針參數)

PS:正如在評論中指出的那樣,「假設我不能自己寫新貼」是錯誤的假設。您無法替換全局位置 - 新建,但您當然可以編寫一個特定於類的位置new,然後通過類作用域查找來獲取。查看cppreference瞭解分配功能的摘要。

+0

爲了解決這個問題,':: new' **或**爲你的班級實施了一個重寫的放置'new'。 – Yakk 2014-09-18 18:12:21

+0

啊,是的,這是有道理的...謝謝!出於某種原因,我完全錯過了ccpreference上提到的註釋: 「即使放置新的(重載5和6)不能被替換,具有相同簽名的函數也可以在類作用域中定義,如上所述」...哎呀。 – YamLady 2014-09-19 10:53:56

1

我建議使用Boost的aligned_allocator

#include <boost/align/aligned_allocator.hpp> 
#include <immintrin.h> 
#include <vector> 

struct m128i { 
    // FIXME: ctors/opers with intrinsics would be nice (required?) 
    __m128i data; 
} 

int main() 
{ 
    std::vector<m128i, boost::alignment::aligned_allocator<m128i, 16> > v; 
    v.emplace_back(); 
} 

注:我已經更新了這個用它包裝的內在成員的結構。有很多這樣的庫。這樣做的原因很簡單:vector_size屬性是將__m128i與__m256i區分開來的,而模板忽略了類型屬性,所以我相信它們最終都會使用相同的擴展,即「long long」(或float/double在非i和d類型的情況下)。

0

我會用我的出發點作爲這裏給出的分配器:http://en.cppreference.com/w/cpp/concept/Allocator。這實際上是一個最小的分配器。特別是,根本不需要寫constructallocator_traits,如果它沒有發現你的分配器有construct方法,將簡單地爲你調用新的位置,正確地調用::(正如Cubbi注意到的)調用,所以你沒有這個問題:http://en.cppreference.com/w/cpp/memory/allocator_traits/construct

我大概不會寫自定義的新/刪除的。只需編寫自定義分配器就足夠了,並讓Vector/Matrix類使用自定義分配器通過std::vector管理其數據。