2014-10-08 63 views
0

假設我有以下核心類:鏈接到在編譯時動態地可用的功能

class Core { 
public: 
    template<typename T> 
    void accept(T object); 
} 

我現在希望能夠寫這樣的方法:

void handle(int par); 

和地方註冊它們期間鏈接/編譯階段並調用Core.accept(T)方法中某個類型名稱註冊的正確方法。例如,在以某種方式註冊之後,呼叫 Core.accept(5)將把5轉移到handle(int)函數。像這樣的東西(不可編譯的例子):

template<typename T> 
void Core::accept(T par) { 
    // constexpr std::map<std::type_info, Function> type_func_mapping; 
    auto it = type_func_mapping.get(typeid(T)); // Should be constexpr 
    static_assert (it != type_func_mapping.end(), "No handler found for typename " + typeid(T).name()) 
    auto function = *it; // Also constexpr 
    function(par); 
} 

這種方法有什麼問題/確實存在更好的嗎?

注意:我希望能夠以可以將它們存儲在只讀標頭/源文件中的方式提取類Core的源,甚至不必再次觸摸它們。

+1

爲什麼你不能定義一個有很多'void handle(int par)的頭文件;無效句柄(double par); void handle(foo_class par);'重載?恐怕我不太明白你的要求和目標是什麼。 – dyp 2014-10-08 21:58:54

+0

作爲上面的註釋,沒有理由有這個奇怪的工廠,從類型映射到功能。你可以根據呼叫類型做功能重載,它會做你想做的一切。 – 2014-10-08 22:09:07

回答

0

您可以使用函數指針來存儲註冊的函數。

static void (*reg_func)(args); 
static void register(void (*func)(args)){ 
reg_func = func; 
} 

//registration part 
register(handle); 

//function call inside accept,use can use some sanity checks also 
reg_func(5 or whatever) 

有了這個,你不必觸碰你的核心類甚至是包含核心類的文件。您可以在其他文件中定義句柄功能,但是可以處理句柄功能的可見性模式。您的句柄功能將自行註冊,然後接受可以調用註冊的功能。

+0

這是編譯時靜態的嗎?我懷疑。這是否適用於一次註冊多個函數(因此不同的模板類型名稱會調用不同的函數)?我看不到那個。隨意給我一個驚喜。 – WorldSEnder 2014-10-08 18:45:31

+0

如果你希望它是編譯時靜態的,Core的代碼沒有辦法「有效地」改變。我的意思是,你可以保持Core.h和Core.cpp一致,但Core.h必須包含一些文件,indirect.h,在添加新類型的句柄函數時必須對其進行修改。最終,我真正想說的是:當你添加新的句柄時,如果你想要編譯時靜態的話,你將需要重新編譯Core.o ...這是完全不可避免的。 – 2014-10-08 22:12:17

相關問題