C++ 静态成员函数的模板专门化;怎么做?

C++ 静态成员函数的模板专门化;怎么做?,c++,templates,boost,C++,Templates,Boost,我正在尝试使用模板专门化实现一个具有不同句柄的模板函数 以下代码为我提供了gcc中的“非命名空间范围中的显式专门化”: 模板 静态T安全调用(boost::function\u f) { 如果(_f.empty()) 抛出异常(“函数指针为空”); { 护丝板g; T ret=_f(); 返回ret; } } //没有返回值的函数的模板专门化 模板 静态void safeGuiCall(boost::function\u f) { 如果(_f.empty()) 抛出异常(“函数指针为空”); {

我正在尝试使用模板专门化实现一个具有不同句柄的模板函数

以下代码为我提供了gcc中的“非命名空间范围中的显式专门化”:

模板
静态T安全调用(boost::function\u f)
{
如果(_f.empty())
抛出异常(“函数指针为空”);
{
护丝板g;
T ret=_f();
返回ret;
}
}
//没有返回值的函数的模板专门化
模板
静态void safeGuiCall(boost::function\u f)
{
如果(_f.empty())
抛出异常(“函数指针为空”);
{
护丝板g;
_f();
}
}

我曾尝试将其移出类(该类未模板化)并移到命名空间中,但随后出现错误“显式专门化不能有存储类”。我读过很多关于这个的讨论,但是人们似乎不同意如何专门化函数模板。有什么想法吗?

您可以用与在类外定义成员函数相同的方式声明显式专业化:

class A
{
public:
  template <typename T>
  static void foo () {}
};

template <>
void A::foo<void> ()
{
}
A类
{
公众:
模板
静态void foo(){}
};
模板
void A::foo()
{
}

您的问题似乎在于boost::function—以下专业化工作:

template <typename T>
T safeGuiCall()
{
    return T();
}

template <>
void safeGuiCall<void>()
{
}

int main() {
    int x = safeGuiCall<int>();     // ok
    //int z = safeGuiCall<void>();  // this should & does fail
    safeGuiCall<void>();            // ok
}
模板
T safeGuiCall()
{
返回T();
}
模板
void safeGuiCall()
{
}
int main(){
int x=safeGuiCall();//确定
//int z=safeGuiCall();//这应该失败(&D)
safeGuiCall();//确定
}

这不是对你问题的直接回答,但你可以写出来

template <typename T>
static T safeGuiCall(boost::function<T ()> _f)
{
        if (_f.empty())
                throw GuiException("Function pointer empty");
        {
                ThreadGuard g;
                return _f();
        }
}
模板
静态T安全调用(boost::function\u f)
{
如果(_f.empty())
抛出异常(“函数指针为空”);
{
护丝板g;
返回_f();
}
}
即使_f()返回'void'它也应该工作


编辑:在更一般的情况下,我认为我们应该更喜欢函数重载而不是专门化。这里有一个很好的解释:

当您专门化一个模板化方法时,您必须在类括号之外这样做:

template <typename X> struct Test {}; // to simulate type dependency

struct X // class declaration: only generic
{
   template <typename T>
   static void f( Test<T> );
};

// template definition:
template <typename T>
void X::f( Test<T> ) {
   std::cout << "generic" << std::endl;
}
template <>
inline void X::f<void>( Test<void> ) {
   std::cout << "specific" << std::endl;
}

int main()
{
   Test<int> ti;
   Test<void> tv;
   X::f( ti ); // prints 'generic'
   X::f( tv ); // prints 'specific'
}
模板结构测试{};//模拟类型依赖关系
结构X//类声明:仅通用
{
模板
静态孔隙f(试验);
};
//模板定义:
模板
void X::f(测试){

std::cout我有一个类似的问题。如果你看原始帖子,我将第一个静态保留在中,但去掉了第二个,两个错误都消失了。

谢谢你的回答。对我来说,它们是否在类中并不重要;但我无法让它以任何方式工作。我的语法错误还是我提供的代码中有什么错误?关键是你没有XPLAULY使用一个有资格的函数声明器来在命名空间中专门化函数。C++不允许你重新添加“static”关键字,所以你只需要删除它。上面的例子告诉你如何明确地专门化一个静态成员。抱歉尝试了这个,但是不起作用。你在GCC下编译了吗?我认为它在VS下工作。例如,它是ise静态-删除它们,所有都应该是weel,它使用comeau编译,我将更新答案。我现在尝试了相同的方法,但将其放入.hpp文件并尝试包含它…然后我得到错误“vodi X:ff的多定义(测试)。我看不出有什么区别?是编译器错误还是链接器错误?如果是编译器错误,则意味着您可能多次包含模板头,并且缺少头保护,因此出现了双重定义:编译器看到了两个(唉,完全正确)实现的定义。为什么我要为第一个案例添加内联?如果不是,我将得到一个编译错误。@sop:我不确定第一个案例指的是什么…模板函数不需要
内联
,如果将定义放在标题中,模板专门化需要它(以避免ODR冲突)这是关于专门化的;如果我将它从header移动到.cpp(并且在header中仍然有模板),我仍然会得到多个定义的错误或错误
template <typename X> struct Test {}; // to simulate type dependency

struct X // class declaration: only generic
{
   template <typename T>
   static void f( Test<T> );
};

// template definition:
template <typename T>
void X::f( Test<T> ) {
   std::cout << "generic" << std::endl;
}
template <>
inline void X::f<void>( Test<void> ) {
   std::cout << "specific" << std::endl;
}

int main()
{
   Test<int> ti;
   Test<void> tv;
   X::f( ti ); // prints 'generic'
   X::f( tv ); // prints 'specific'
}
template <typename X> struct Test {}; // to simulate type dependency

template <typename T>
void f( Test<T> ) {
   std::cout << "generic" << std::endl;
}
template <>
void f<void>( Test<void> ) {
   std::cout << "specific" << std::endl;
}

int main()
{
   Test<int> ti;
   Test<void> tv;
   f( ti ); // prints 'generic'
   f( tv ); // prints 'specific'
}