【发布时间】:2022-12-13 01:35:29
【问题描述】:
我正在练习 C++,我想使用模板实现一些数据结构。
我想为 List<char> 创建一个接受 C++ string 作为参数的构造函数,但我不想为其余类型创建这样的构造函数(因为创建一个List<double> 来自 string,例如)。
有没有办法在 C++ 中实现这一点?
这是我的代码:
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
template <typename T> class CollectionInterface {
public:
virtual T get();
virtual void set(int index, T value);
virtual void add(T value);
virtual int length();
};
template <typename T> class ListItem {
public:
T value;
ListItem* next;
ListItem* prev;
};
template <typename T> class List: public CollectionInterface<T> {
public:
List(){}
List(T* arr, int length){
init(arr,length);
}
~List(){
}
protected:
void init(T* arr, int length){
}
ListItem<T>* first;
ListItem<T>* last;
};
template<char> class List<char> {
public:
List<char>(string s){
char char_array[s.length() + 1];
strcpy(char_array, s.c_str());
this->init(char_array,s.length());
}
};
int main()
{
List<char> list("Hello World!");
//cout << "Hello World!" << endl;
return 0;
}
它显示以下错误:
第 40 行:“List”的部分特化不使用其任何模板参数
第 45 行:“List<char>”中没有名为“init”的成员
【问题讨论】:
-
完全专门化模板类是
template<> class List<char> { ... };。 -
此外,VLA 不是标准的一部分,因此不应使用。无论如何都不需要这样做:
this->init(s.data(), s.length());应该可以解决问题,您可能还是想在这里创建一个副本,所以如果您将init的签名更改为void init(T const* arr, int length),this->init(s.c_str(), s.length());可能就足够了 -
有没有办法从 List<char> 中调用非专用函数?我收到错误消息:“List<char>”中没有名为“init”的成员
-
不幸的是,当我正在寻找答案时这个问题已经结束,但基本上我会在类之外实现转换并引入一个通过概念(或 SFINAE pre C++20)限制的构造函数模板。这是我用简化类创建的示例:godbolt.org/z/Yn7GYMTsc
标签: c++ c++-templates