类模板外部可以专门化类模板中的模板函数吗?

3

类模板中的模板函数可以在类模板外进行专门化吗?它的语法是什么?

在MSVC2010中,以下代码会提示“无法将函数定义与现有声明匹配”的错误。

#include <iostream>

template <typename T>
struct Test
{
    template <typename S>
    void test(const S & t);

    //this works
    //template<> void test(const double & t) { std::cout << t << "D \n"; }

    T member;
};

//this doesn't work
template <typename T>
template <>
void Test<T>::test(const double & t)
{
    std::cout << t << "D \n";
}

int main()
{
    Test<int> t;
    t.test(7.0);
}

编辑

我可以按照答案中的建议使用重载,因为我使用它的方式略有不同,具体如下:

#include <iostream>

template <typename T>
struct Test
{
    template <typename S>
    void test() { std::cout << "Any type \n"; }

    template <>
    void test<double>() { std::cout << "Double! \n"; }

    T member;
};

int main()
{
    Test<int> t1;
    Test<int> t2;
    t1.test<float>();
    t2.test<double>();
}

我希望你能为struct外的double类型提供专门的翻译。

你可能会问我为什么要这样使用?实际情况是,我已经建立了一个工厂类,用法如下:

Factory<SomePolicy> f;
f.create<MyType>(arg1, arg2, ...)

我需要针对特定类型进行create的专门化,以避免污染头文件。


空的 template <> 不能跟随非空的 template <typename S>。因此,你只能写类似于这样的代码:template <> template <typename S> void Test<double>::test(const S & t){/*...*/},但这显然不是你想要的。而且你也不能在类声明中声明或定义特化。 - Constructor
2个回答

0

我不相信你可以在不专门化外部模板的情况下专门化内部模板。但是,你可以使用部分专门化:

编辑:似乎只有类可以进行部分专门化。再次声明,我没有测试过。你可以在这里找到更多信息。

template <typename T, typename S>
struct Test 
{
   void test(const S &s);
};

template <typename T>
struct Test<T, float>
{
   void test (const float &s)
   {
      <<do something>>
   }
}

我认为在示例代码中使用struct而不是class是有道理的。否则,您必须明确标记一些内容为public - Brian Bi
谢谢您的回答,但我认为不太好。1)这是无法编译的,2)类模板具有2个模板参数和具有一个参数和模板成员函数的类模板之间存在很大差异。 - relaxxx
@Brian 这就是我为什么使用结构体的原因。 - relaxxx
我说过我还没有运行代码。而且,它部分是错误的。正在进行编辑。 - muppetjones

0
据我所知,你不能这样做。但你可以按照以下方式重载你的test函数:
template <typename T>
struct Test
{
    template <typename S>
    void test(const S & t);

    void test(const double &); // <-- Add this

    T member;
};

template <typename T> 
// template<> // <-- Remove this
void Test<T>::test(const double & t)
{
    std::cout << t << "D \n";
}

这应该完全等同于你想要做的。


谢谢您的回答,不幸的是,在我的情况下这不起作用。请查看我问题的编辑。 - relaxxx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接