声明后初始化C ++模板类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了声明后初始化C ++模板类相关的知识,希望对你有一定的参考价值。

我使用SinglyLinkedList创建了一个template <class T>模板类。例如,如果我输入“string”作为我的命令行参数,我想创建SinglyLinkedList<string>* string_list = new SinglyLinkedList<string>();。如果我输入“number”作为我的命令行参数,我想创建SinglyLinkedList<string>* number_list = new SinglyLinkedList<string>();

有没有办法可以将它结合起来,以便按照以下方式做一些事情:

SinglyLinkedList<>* list;
if (argv[0] == "string") {
    list = new SinglyLinkedList<string>();
} else if (argv[1] == "number") {
    list = new SinglyLinkedList<int>();
}

如果我现在这样做,第一行会抛出错误invalid template code

有没有办法在C ++ 11中执行此操作?

答案

如果将整个列表处理放入通用函数中,事情可能会更容易:

template<typename Item>
void process_list() {
  SinglyLinkedList<Item>* list = new SinglyLinkedList<Item>();
  Item it;
  if (std::cin >> it) {
     list->push(it);
  }
}

这样,您可以对Item类型的通用项进行所有处理,并且在调用函数时只需要区分类型一次:

int main(int argc, const char **argv) {
    if (argv[0] == "string") {
        process_list<string>();
    } else if (argv[1] == "number") {
        process_list<int>();
    }
}
另一答案

模板实例化是独立的类,因此没有共同的基类,但解决这个问题的一种方法是显式定义基类:

// Empty base class
class SinglyLinkedBase {};

template <typename T>
class SinglyLinkedList : public SinglyLinkedBase
{
    // As before
};

SinglyLinkedBase* list;
if (argv[0] == "string") {
    list = new SinglyLinkedList<string>();
} else if (argv[1] == "number") {
    list = new SinglyLinkedList<int>();
}

另外,Boost::anystd::any(如果你有一个C ++ 17编译器)可以在没有虚拟基类的情况下做到这一点。

另一答案

您正在使用运行时类型确定。

在这种情况下,如果您仍想使用相同的变量“list”,则其类型应为抽象基指针。只需使用How do boost::variant and boost::any work?中显示的“类型擦除”技巧

或者就像在答案中所示,您可能在不同的模板实例中有两个不同类型的本地版本。

如果要传递非模板参数,请记住使用

process_list<string>(in_file)而不是process_list(in_file)

以上是关于声明后初始化C ++模板类的主要内容,如果未能解决你的问题,请参考以下文章

C++string类总结

c ++了解C ++模板类的初始化列表

c ++由于命名空间导致无法解释的类“尚未声明”错误

C ++类成员函数别名模板,防止大括号括起来的初始化程序列表被识别为对/元组

C++17 模板类初始化的折叠表达式的限制类型

Reactreact概述组件事件