将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的第一个参数: int
, float
, double
,whatever。
现在如果你真的想把第一个参数的types限制为只有int
, float
或者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在幕后为你做的。