2011-09-01 51 views
3

我有一個聲明像一個函數:強制模板函數實例在

template<typename T> 
void MyFunction(); 

和A類:

template<typename T> 
class MyClass 
{ 
public: 

    typedef void (*Function_T)(); 
    Function_T m_Func; 
    void DoSomething() 
    { 
     m_Func = &MyFunction<T>; 
    } 
} 

當我使用類,我就MyFunction<T>未定義的符號錯誤。
如果我改變DoSomething

void DoSomething() 
{ 
    m_Func = &MyFunction<T>; 
    return; 
    MyFunction<T>(); 
} 

一切正常,但看起來像一個解決辦法,將可能無法與優化工作。
我不能添加

template void MyFunction<T>; 

到類,因爲它說,它不能在課堂上。有沒有其他方法可以強制實例化函數?

編輯:
我能夠寫一個失敗的測試,但在G ++它有不同的消息,實際上是一個編譯器錯誤:http://ideone.com/RbMnh

+0

是否'MyFunction'有身體? – AJG85

+0

@ AJG85:它確實在同一個地方,但它不是解決問題的方法。 – Dani

+0

什麼編譯器和版本?你是否意識到'Function_T'不是一個函數指針,而是一個'void *'?在實例化處可以使用「MyFunction」的定義嗎? –

回答

3

你的代碼將與優化工作,以及。雖然,我不知道爲什麼簡單地m_Func = &MyFunction<T>不起作用。 GCC 4.3.4 compiles it fine。你正在使用哪個編譯器?

而且你還可以這樣做:

void DoSomething() 
{ 
    if (false) MyFunction<T>(); 
    m_Func = &MyFunction<T>; 
    return; 
} 

順便說一句,函數指針類型定義不正確。它應該是這樣的:

typedef void (*Function_T)(); 
        // ^^ put this! 
+0

這可能會受到他擔心的相同優化問題的影響,不是嗎? –

+0

函數指針是複製錯誤。我正在使用clang編譯器。 – Dani

+0

我已經嘗試過使用clang ++ 2.8 release 28,它編譯和鏈接完美,你使用的編譯器的確切版本是什麼?你可以創建一個展示行爲的最小完整程序嗎? –

3

您的代碼編譯好我使用GCC的,所以我不知道,如果這個解決方案可以解決您的具體問題,但可以明確的實例化模板函數,像這樣:

// Template function defined: 
template <typename T> 
void MyFunction() { 
    // body 
} 

// Template function instantiated: 
template void MyFunction<int>(); 
+0

我轉載它有點不同,看看編輯。 – Dani

0

該問題可能是編譯器錯誤,也可能是您沒有顯示的代碼部分中的錯誤。嘗試建立能重現問題小例子,這是最小的例子,我已經能夠生產,而且編譯罰款既鏗鏘++ 2.8和g ++ 4.4/4.5:

[email protected]:/tmp$ cat test.cpp 
#include <iostream> 

template <typename T> 
void function() { 
} 

template <typename T> 
struct type { 
    typedef void (*Func)(); 
    Func _f; 
    void f() { 
     _f = &function<T>; 
    } 
}; 

int main() { 
    type<int> t; 
    t.f(); 
    std::cout << t._f << std::endl; 
} 
[email protected]:/tmp$ /usr/bin/clang++ --version 
clang version 2.8 (branches/release_28) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 
[email protected]:/tmp$ /usr/bin/clang++ -o test test.cpp && ./test 
1 
[email protected]:/tmp$ g++ --version 
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

[email protected]:/tmp$ g++-4.4 -o test test.cpp && ./test 
1 
+0

我轉載了一下,看看編輯。 – Dani

+0

@Dani:這是一個完全不同的錯誤,這是由於類型不匹配的事實,'&C '具有'void(*)(int)'類型,並且您試圖將其轉換爲'void (*)()',這個錯誤可能會引起誤解,但如果你修改了cast(這是缺少的上下文信息),那麼錯誤就會消失(呃,由於參數不匹配,錯誤會被轉換成另一個錯誤接收端的類型... http://ideone.com/Fh0Nx –

+0

我需要這個cast。clang在這種情況下會出現鏈接器錯誤 – Dani