2011-09-01 56 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