将string文字作为parameter passing给C ++模板类

我想要一个在构造函数中使用两个参数的类。 第一个可以是int,double或float,所以<typename T> ,第二个总是一个string文字“my string”,所以我猜const char * const。

任何人都可以给我一些可编译的代码,声明一个简单的类模板描述和声明该类的对象?

谢谢

对不起,C ++目前不支持使用string文字(或真正的文字)作为模板参数。

但重新阅读你的问题,你在问什么? 你不能说:

 foo <"bar"> x; 

但你可以说

 template <typename T> struct foo { foo( T t ) {} }; foo <const char *> f( "bar" ); 

进一步从Neil的回答:一个使用string与模板的方法是想定义一个traits类,并将string定义为types的特征。

 #include <iostream> template <class T> struct MyTypeTraits { static const char* name; }; template <class T> const char* MyTypeTraits<T>::name = "Hello"; template <> struct MyTypeTraits<int> { static const char* name; }; const char* MyTypeTraits<int>::name = "Hello int"; template <class T> class MyTemplateClass { public: void print() { std::cout << "My name is: " << MyTypeTraits<T>::name << std::endl; } }; int main() { MyTemplateClass<int>().print(); MyTemplateClass<char>().print(); } 

版画

 My name is: Hello int My name is: Hello 

这是MPLLIBS传递一个string作为模板参数(C ++ 11)的解决scheme。

 #include <iostream> #include <mpllibs/metaparse/string.hpp> // https://github.com/sabel83/mpllibs #include <boost/mpl/string.hpp> // -std=c++11 template<class a_mpl_string> struct A { static const char* string; }; template<class a_mpl_string> const char* A< a_mpl_string > ::string { boost::mpl::c_str< a_mpl_string >::value }; // boost compatible typedef A< MPLLIBS_STRING ( "any string as template argument" ) > a_string_type; int main ( int argc, char **argv ) { std::cout << a_string_type{}.string << std::endl; return 0; } 

打印:

 any string as template argument 

github上的lib: https : //github.com/sabel83/mpllibs

 inline const wchar_t *GetTheStringYouWant() { return L"The String You Want"; } template <const wchar_t *GetLiteralFunc(void)> class MyType { void test() { std::cout << GetLiteralFunc; } } int main() { MyType<GetTheStringYouWant>.test(); } 

试着把一个函数的地址作为模板参数。

根据你在Niel的回答下的意见,另一种可能性如下:

 #include <iostream> static const char* eventNames[] = { "event_A", "event_B" }; enum EventId { event_A = 0, event_B }; template <int EventId> class Event { public: Event() { name_ = eventNames[EventId]; } void print() { std::cout << name_ << std::endl; } private: const char* name_; }; int main() { Event<event_A>().print(); Event<event_B>().print(); } 

版画

 event_A event_B 

我想要一个在构造函数中使用两个参数的类。 第一个可以是int,double或float,所以,第二个总是一个string文字“my string”

 template<typename T> class demo { T data; std::string s; public: demo(T d,std::string x="my string"):data(d),s(x) //Your constructor { } }; 

我不确定,但是这是你想要的东西吗?

一个string文字“我的string”,所以我猜const char * const

实际上,带有n个可见字符的string是const char[n+1]

 #include <iostream> #include <typeinfo> template<class T> void test(const T& t) { std::cout << typeid(t).name() << std::endl; } int main() { test("hello world"); // prints A12_c on my compiler } 

编辑:好吧,你的问题的标题似乎是误导

“我想要一个在其构造函数中使用两个参数的类,第一个可以是int,double或float,所以第二个总是一个string”my string“,所以我猜const char * const。

它看起来像你试图达到:

 template<typename T> class Foo { public: Foo(T t, const char* s) : first(t), second(s) { // do something } private: T first; const char* second; }; 

这将适用于任何types的第一个参数: intfloatdouble ,whatever。

现在如果你真的想把第一个参数的types限制为只有intfloat或者double ; 你可以拿出更详细的东西

 template<typename T> struct RestrictType; template<> struct RestrictType<int> { typedef int Type; }; template<> struct RestrictType<float> { typedef float Type; }; template<> struct RestrictType<double> { typedef double Type; }; template<typename T> class Foo { typedef typename RestrictType<T>::Type FirstType; public: Foo(FirstType t, const char* s) : first(t), second(s) { // do something } private: FirstType first; const char* second; }; int main() { Foo<int> f1(0, "can"); Foo<float> f2(1, "i"); Foo<double> f3(1, "have"); //Foo<char> f4(0, "a pony?"); } 

如果你删除最后一行的注释,你将会得到一个编译器错误。


string文字不被C ++ 2003允许

ISO / IEC 14882-2003§14.1:

14.1模板参数

非types的模板参数应该具有以下(可选的CV-限定)types之一:

– 积分或枚举types,

– 指向对象或指向函数的指针,

– 引用对象或引用的function,

– 指向成员的指针。

ISO / IEC 14882-2003§14.3.2:

14.3.2模板非types参数

非types的非模板模板参数的模板参数应该是以下之一:

– 积分或枚举types的积分常量expression式; 要么

– 非types模板参数的名称; 要么

– 具有外部链接的对象或函数的地址,包括函数模板和函数模板id,但不包括非静态类成员,表示为&idexpression式,其中&是可选的(如果名称引用函数或数组)相应的模板参数是一个参考; 要么

– 一个指向成员的指针,如5.3.1所述。

[注:string文字(2.13.4)不符合任何这些类别的要求,因此不是可接受的模板参数。

[例:

 template<class T, char* p> class X { //... X(); X(const char* q) { /* ... */ } }; X<int,"Studebaker"> x1; //error: string literal as template-argument char p[] = "Vivisectionist"; X<int,p> x2; //OK 

– 例子] – 结束注释]

在即将到来的C ++ 0X中它看起来不会改变, 请参阅当前草案14.4.2模板非types参数 。

您不能直接将string文字作为模板parameter passing。

但是你可以closures:

 template<class MyString = typestring_is("Hello!")> void MyPrint() { puts( MyString::data() ); } ... // or: MyPrint<typestring_is("another text")>(); ... 

所有你需要的是一个小的头文件从这里 。


备择scheme:

  • 定义一个全局的char const *并将其作为指针传递给模板。 ( 这里 )

    缺点:需要模板参数列表之外的其他代码。 如果你需要指定string“inline”,这是不合适的。

  • 使用非标准的语言扩展。 ( 这里 )

    缺点:不保证与所有编译器一起工作。

  • 使用BOOST_METAPARSE_STRING 。 ( 这里 )

    缺点:你的代码将取决于Boost库。

  • 使用char的可变参数模板参数包,例如str_t<'T','e','s','t'>

    这就是上面的解决scheme在幕后为你做的。