字符串类型的 C++ 模板无法编译
c++ template with string type cannot compile
我正在尝试这样做,但它无法编译。我想做的是定义一个模板类专用化实现。并创建它的一种类型。我可以用 int 类型来做,但是当我尝试使用 string 时我遇到了很多麻烦。
#include <iostream>
using namespace std;
template <char const *str>
struct X
{
};
constexpr char global_string[] = "String";
template<>
struct X<global_string>
{
typedef int mytype;
const char *GetString() const
{
return global_string;
}
};
constexpr char version_use[] = "String";
int main()
{
using X1= X<version_use> ;
X1::mytype t = 1;
//X1 x;
//cout<<x.GetString() << " " << t;
}
sh-4.2$ g++ -std=c++11 -o main *.cpp
main.cpp: In function 'int main()':
main.cpp:27:5: error: 'mytype' is not a member of 'X1 {aka X<((const char*)(& version_use))>}'
X1::mytype t = 1;
^
main.cpp:27:16: error: expected ';' before 't'
X1::mytype t = 1;
> Bryan要求举一个使用typeid的例子。这是我前几天做的东西,作为编译时多态数据存储的实验。目标是在客户端级别获得优雅的语法,将"任何内容"(有一些限制)放入列表中:
template <typename T> const char* Type()
{
static const char *s = typeid(T).name();
return s;
}
模板函数 + 静态变量可确保每个项目仅生成此字符串的一个副本。然后可以打印出类型名称,或者可以在运行时比较两个对象的指针值。我将其作为动态类型存储实验的一部分。如果有人感兴趣或收到对这种方法的评论/批评,我将提供代码。基本上,下面的代码创建一个"nodeBase"对象,然后创建一个"node
// stores type string and used to compare types at runtime
template <typename T> const char* Type() { static const char *s = typeid(T).name(); return s; }
// nodeBase parent class, with virtual function Data
struct nodeBase
{
nodeBase *next = 0;
const char *type;
int size;
virtual ~nodeBase() {};
virtual void *Data() = 0;
};
// child class for data structures that have copy constructors
template <typename T> struct node : public nodeBase // template for storing regular structs and stuff
{
T data;
node(T _data) : data(_data)
{
type = Type<T>();
size = sizeof(data);
}
~node() {}
void *Data() {
return &data;
}
};
// template specialization just for "char *" strings
template <> struct node<const char*> : public nodeBase // this is a template specialization just for strings
{
char *data;
node(const char *_data)
{
type = Type<const char*>();
size = strlen(_data) + 1;
data = new char[size];
strcpy_s(data, size, _data);
}
~node() { delete data; }
void *Data() { return data; }
};
// create function makes node<T> and returns base class pointer
template <typename T> nodeBase *create(T data) { return new node<T>(data); }
template specialization of "create" function to pack in std::strings as just "char *" strings
template <> nodeBase *create<std::string>(std::string data) { return create(data.c_str()); }
// this function needs to expand according to what types you want to retrieve
void displayNode(nodeBase *n)
{
if (!n) return;
std::cout << n->type << "( " << n->size << " bytes ) ";
if (n->type == Type<float>())
{
std::cout << " = " << *(float *)(n->Data()) << std::endl;
}
else if (n->type == Type<double>())
{
std::cout << " = " << *(double *)(n->Data()) << std::endl;
}
else if (n->type == Type<char const *>())
{
std::cout << " = " << (const char *)n->Data() << std::endl;
}
else
{
std::cout << " = " << *(int *)n->Data() << std::endl;
}
}
// really simple stack implementation for storing a list
class stack
{
public:
nodeBase *head = nullptr;
unsigned int count;
~stack()
{
while (head)
{
nodeBase *temp = head;
head = head->next;
delete temp;
}
}
// custom templated push function
template <typename T> void push(T data)
{
nodeBase *new_node = create(data);
new_node->next = head;
head = new_node;
count++;
}
// quick and dirty [] operator to access the values for the print test
nodeBase *operator[](int index)
{
nodeBase *node = head;
while (index > 0 && node != nullptr)
{
node = node->next;
index--;
}
return node;
}
};
struct Cat { int whiskers = 1000; };
int test_list_multi()
{
stack list1;
// pushes a bunch of junk into the list to show it really can store just about anything without needing obtuse syntax
list1.push(44);
list1.push(2.0423423432f);
list1.push("drugs");
list1.push(std::string("hello"));
list1.push(bool(true));
list1.push(2.4545);
list1.push('a');
list1.push(short(66));
list1.push([] { int a, b; });
list1.push([] { int a; });
struct Dog { int legs[4]{ 9,9,9,9 }; char tail{ 't' }; };
Dog dog;
Cat cat;
list1.push(dog);
list1.push(cat);
std::cout << "count = " << list1.count << std::endl;
// go through the list and display details for each node including type and value
for (int i = 0; i < list1.count; ++i)
{
displayNode(list1[i]);
}
std::cin.ignore();
std::cin.get();
return 0;
}
相关文章:
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 使用简单类型列表实现的指数编译时间.为什么
- 编译标准库类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 非类型指针和引用模板参数,以及在编译时如何/为什么解析它们.c++
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- 为什么 std::make_shared 无法编译带有已删除运算符 new 的类型?
- 标量类型的特征模板无法编译固定大小的子矩阵操作
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- 由于类型从 C 转换为 C++,无法编译错误 C2440
- 通过编译时值推断整数的类型
- 基于派生类型的编译时行为分支
- C++ 编译错误:gnu_printf是无法识别的格式函数类型
- 将函数类型作为模板参数传递不会编译
- 编译类型的时静态数组
- 警告LNK4206:找不到预编译类型信息; 未链接或覆盖;链接对象,就好像没有调试信息一样
- GCC 编译类型错误:预期的类型说明符
- c++编译类型资源所有者断言
- 基于字符串的类型层次结构,带有编译类型检查