功能专门用于模板

时间:2014-05-08 18:56:23

标签: c++ templates template-specialization

我需要使用模板类对我的函数进行专门化,并且对#34;非法使用显式模板参数存在问题"。

template <typename T>
class MyClass { /* ... */ }; // it can be any template class, eg std::vector

template <typename T>
void foo() { /* ... */ } // my template function which need a specialization

template<> 
void foo<int>() /* sth special for integers - it works */ }

template<template T> 
void foo<MyClass<T> >() /* sth special for template class with any parameter - it doesnt work :( */ }

当然,我可以为我需要的所有MyClass键入一些专门化,但是也许它可以替换为一个?

4 个答案:

答案 0 :(得分:5)

函数的模板特化不像struct的特化那样灵活:只允许完全特化。如果您想进行部分专业化,则需要将foo函数包含在struct内:

template <typename T> class MyClass { };

template <typename T> struct Foo;

template <typename T> struct Foo { void foo() {}};

template<> struct Foo<int> { void foo() { } };

template<typename T> struct Foo< MyClass<T> > { void foo() {} };

然后而不是打电话

foo<MyClass<...>>()
你打电话

Foo< MyClass<...> >::foo()

答案 1 :(得分:2)

您不能部分特殊化模板功能。有关于删除该限制的讨论。

提倡的解决方法是:

  1. 使用模板函数中的类模板。
  2. 将您的功能包装在模板类中。
  3. template <typename T>
    struct foo_impl {
    };
    template <typename T>
    void foo() {
        foo_impl<T>();
    }
    
    // And now specialize foo_impl as you want:
    
    template<>
    struct foo_impl<int> {
        foo_impl(){/* sth special for integers - it works */}
    };
    template<typename T>
    struct foo_impl<myclass<T>> {
       foo_impl() {/* ... */}
    };
    

    如果你想要一个返回值,你应该使用一个成员函数 - 可能是operator() - 而不是ctor。

答案 2 :(得分:1)

可能的解决方案可能是使用基类

template<typename T> class MyClass;

class base {
private:
    template<typename T> friend class MyClass;
    base(); // Can't build a base object directly
};

template <typename T>
class MyClass : public base { 
public:
}; // it can be any template class, eg std::vector

template <typename T>
void foo() {
} // my template function which need a specialization

template<> 
void foo<int>() { /* sth special for integers - it works */ }

template<>
void foo<base>() { /* sth special for template class with any parameter - it doesnt work :( */ }

如果您希望模板参数适用于您的功能,上述操作也可能有效。如果你可以将你的功能包起来,我可以使用hivert的解决方案。

答案 3 :(得分:1)

这是一个额外的打字,但如何:

template <typename T>
class MyClass { /* ... */ }; // it can be any template class, eg std::vector

template<typename T>
struct FooWrapper
{
    static void foo()
    {
       // default implementation
    }
};

template<typename T>
struct FooWrapper<MyClass<T>>
{
    static void foo()
    {
        // MyClass<T> implementation
    }
};

template<typename T>
void foo()
{
    FooWrapper<T>::foo();
}