【问题标题】:template class for specific data type特定数据类型的模板类
【发布时间】:2019-04-01 00:17:42
【问题描述】:

(为了简单起见,代码被简化了) 我想创建一个带有模板 E A 的测试类,以及一个只有 E 模板的测试类。当我这样做并尝试编译我的代码时,我得到了这些错误:

错误 C2976:“测试”:模板参数太少

注意:参见“测试”的声明

错误 C2244:“Test::Output”:无法将函数定义与 现有声明

错误 C2662: 'void Test::Output(void)': 无法转换 'this' 从“测试”到“测试&”的指针

错误 C2514:“测试”:类没有构造函数

#include <iostream>
#include <string>
template <typename E, typename A>
class Test
{
public:
    Test(E *e = nullptr, A *a = nullptr) : a(e), b(a) {}
    void Output();

private:
    E * a;
    A *b;
};
template <typename E, typename A>
void Test<E, A>::Output()
{
    std::cout << " " << *a << " " << *b;
}

template <typename E>
class Test
{
public:
    Test(E *e = nullptr, std::string *a = nullptr) : a(e), b(a) {}
    void Output();

private:
    E * a;
    std::string *b;
};

template<typename E>
void Test<E>::Output()
{
    std::cout << *a << *b;
}
int main()
{
    int a = 10;
    std::string str = "hi";

    Test<int> t(&a, &str);
    t.Output();
    return 0;
}

【问题讨论】:

    标签: c++ class oop templates


    【解决方案1】:

    类模板不能重载(函数模板可以),而只能是特化的。如果你想要partial specialization,应该是

    template <typename E>
    class Test<E, E>
    {
        ...
    };
    

    template<typename E>
    void Test<E, E>::Output()
    {
        ...
    }
    

    并且在使用它时,您应该始终指定两个模板参数作为被声明的主模板。即

    Test<int, int> t(&a, &str); // the partial specialization will be used
    

    编辑

    我可以将第二个模板设置为特定的数据类型(例如std::string)吗?并像Test&lt;int, std::string&gt;一样使用Test

    是的。例如

    template <typename E>
    class Test<E, std::string>
    {
        ...
    };
    

    template<typename E>
    void Test<E, std::string>::Output()
    {
        ...
    }
    

    LIVE

    【讨论】:

    • 能否将第二个模板设置为特定的数据类型(如std::string)?并使用 Test 像 Test
    • 是的,我知道可以这样做。但是,如果我想用两个模板参数定义一个类模板 Test,比如 template 并且还专门为 Test 类定义 A is std::string 类型的方法呢?
    • @CharlieLee 我没有完全理解你的问题。你的意思是不偏特化类模板,而只是偏特化成员函数?
    • 我的意思是我可以有一个类模板:例如Test (其中 E 和 A 都是模板)但同时在 A 为 std::string 时定义特定函数
    • @CharlieLee 您必须进行某种特化、类特化(如我的回答所示)或成员函数特化。
    【解决方案2】:

    很遗憾,您不能通过声明 template typename E&gt; class Test 来“重载”类模板。 Test 类必须带两个模板参数。

    这里的解决方案是声明一个完全不同的模板类或使第二个模板参数可选并编写模板特化:

    class Dummy;
    template <typename E, typename A = Dummy>
    class Test
    …
    
    template <typename E>
    class Test<E, Dummy>
    

    所以语法 Test&lt;int&gt; t(&amp;a, &amp;str); 仍然有效。

    【讨论】:

      猜你喜欢
      • 2017-04-04
      • 1970-01-01
      • 2014-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多