我正在尝试这样做,但它无法编译..我想要做的是定义模板类专门化实现。并创建它的类型..我可以使用int类型,但我尝试使用字符串时遇到了很多麻烦..
#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;
答案 0 :(得分:0)
布莱恩问了一个使用typeid的例子。这是我前几天作为编译时多态数据存储实验的一些东西。目标是在客户端级别获得优雅的语法,将“任何”(有一些限制)放入列表中:
template <typename T> const char* Type()
{
static const char *s = typeid(T).name();
return s;
}
模板函数+静态变量确保每个项目只生成此字符串的一个副本。然后可以打印出类型名称,或者可以在运行时比较两个对象的指针值。我把它作为动态类型存储实验的一部分。如果有人有兴趣或接受对此方法的评论/批评,我会提供代码。基本上下面的代码创建一个“nodeBase”对象,然后创建一个“node&lt; T&gt;”这是nodeBase的子类。 nodeBase本身是一个抽象类,因此它永远不会被创建。所有真实节点都是多态节点&lt; T>类型。 nodeBase形成一个可以推送项目的堆栈,它们可以是任何类型。一个节点&lt; T>子类和一个类型&lt; T>为您尝试和存储的每种不同类型创建功能。存储类型在编译时确定,但可以在运行时从集合中正确推断类型。请注意,c ++ 17中的std :: any可能会使以下想法过时:
// 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;
}