請考慮下面的代碼:外部定義的函數指針作爲模板參數
main.cpp中:
#include <iostream>
typedef void (* fncptr)(void);
extern void externalfunc(void);
template<void(* test)(void)>
class Bar
{
public:
Bar() { test(); }
};
void localfunc()
{
std::cout << "Hello World" << std::endl;
}
constexpr fncptr alias = localfunc;
extern fncptr externalAlias;
int main(int argc, char* argv[])
{
Bar<localfunc> b;
Bar<alias> b2; // This wouldn't compile if alias wasn't constexpr
Bar<externalfunc> b3;
// Bar<externalAlias> b4;
return 0;
}
和external.cpp:
#include <iostream>
typedef void (* fncptr)(void);
void externalfunc()
{
std::cout << "Hello external world" << std::endl;
}
fncptr externalAlias = externalfunc;
現在的問題是我需要的東西,如第四行主要功能工作。我從外部C庫中獲得這些函數聲明,因此我無法觸及這些函數聲明。目前第四行不能編譯。 gcc 4.6表示「它必須是具有外部連接功能的地址」。事實上,如果你使alias
不是constexpr,那麼它也會這樣說,所以實際的含義(我認爲)應該被解釋爲:「我不知道100%確定你給我的函數地址是不變的,我需要用於實例化這個模板「。有沒有辦法解決這個問題,因爲我無法在main.cpp
中聲明externalalias
爲constexpr
?
在您使用替代解決方案之前:我已經試圖通過只通過構造函數傳遞函數指針並將它們保存在本地來獲得此工作,但如果我能使模板版本工作,我仍然感興趣。
編譯器應該如何知道'externalAlias'的值是什麼,以便它可以實例化模板? –
是的,它不知道'externalAlias'的值,但它是一個變量,因此它在編譯時知道該變量的位置,所以它可以在其上進行模板化。 (如另一個答案(即我的答案:-))所示)。 –
你爲什麼想用模板來做課堂專業化?這就是繼承的原因。 (即test()應該只是一個純粹的虛擬方法Bar)然後在派生類中實現與localfunc,alias,externfunc等相對應的測試......或者更好的是,Bar只是一個獨立的類,在它的構造函數中傳遞了一個「ITest」類的實例。用模板做一些棘手的事情只會導致其他人不可繼承的代碼繼承。 – selbie