我遇到模板问题,如果你尝试给模板化函数一个字符串参数,编译器会将“Hello World”解释为const char [12]。我希望它是const char *。
我可以通过将每个字符串静态转换为'const char *'来'解决'这个问题,但是因为我试图将它作为日志记录系统的一部分使用,所以简单化是一个很大的目标。
由于很难解释我的意思,我想出了一个简单的复制器。您将看到main函数的最后一行无法编译。
非常感谢任何帮助
#include <string>
// Trivial base class so we can use polymorphism
class StoreItemsBase
{
public:
StoreItemsBase() {}
};
// Example of a trivial Templated class to hold some 3 items.
// Intent to have similar classes to hold 4,5..n items
template <typename T1, typename T2, typename T3>
class Store3Items : public StoreItemsBase
{
public:
Store3Items(const T1& t1, const T2& t2, const T3& t3)
:
StoreItemsBase(),
mT1(t1),
mT2(t2),
mT3(t3)
{}
private:
T1 mT1;
T2 mT2;
T3 mT3;
};
// Function to create a pointer to our object with added id
// There would be similar CreateHolderFunctions for 4,5..n items
template <typename T1, typename T2, typename T3>
StoreItemsBase* CreateHolder(const T1& t1, const T2& t2, const T3& t3)
{
return new Store3Items<T1, T2, T3>(t1, t2, t3);
}
int main()
{
int testInt=3;
double testDouble=23.4;
const std::string testStr("Hello World");
StoreItemsBase* Ok1 = CreateHolder(testInt, testDouble, testStr);
StoreItemsBase* Ok2 = CreateHolder(testDouble, testStr, testInt);
StoreItemsBase* Ok3 = CreateHolder(testStr, static_cast<const char*>("Hello there"), testInt);
// If you try a standard string, it compiler complains
// Although I could surround all my strings with the static cast, what I am looking for is a way
// to for the CreateHolder function to do the work for me
StoreItemsBase* NotOk4 = CreateHolder(testStr, "Hello World", testInt);
// Free our objects not shown in the example
}
编译器错误是: example.cpp:在构造函数'Store3Items :: Store3Items(const T1&amp;,const T2&amp;,const T3&amp;)[with T1 = std :: basic_string,T2 = char [12],T3 = int]': example.cpp:50:50:从'StoreItemsBase * CreateHolder(const T1&amp;,const T2&amp;,const T3&amp;)[与T1 = std :: basic_string,T2 = char [12],T3 = int]'实例化 example.cpp:65:74:从这里实例化 example.cpp:21:11:error:用作初始化程序的数组
答案 0 :(得分:5)
您可以使用元函数将作为参数传递的类型转换为模板。任何字符数组都将转换为char*
:
template< typename T > struct transform
{
typedef T type;
};
template< std::size_t N > struct transform< char[N] >
{
typedef char* type;
};
template< std::size_t N > struct transform< const char[N] >
{
typedef const char* type;
};
然后,不要直接使用Tn
,而是使用typename transform< Tn >::type
。
更新:如果您使用的是 C ++ 11 ,那么std::decay
已经达到了您想要的效果。
答案 1 :(得分:0)
尝试将模板参数更改为const T1 t1,const T2 t2,const T3 t3。它的性能会降低,但它会编译
基于模板参数确定函数参数通常很困难。您可以尝试使用类构造函数签名。我使用类“arg_type”(非标准)的模板特化来确保所有不是const指针的参数类型都由const ref传递,所有的const指针都作为const指针传递。
另外,不要忘记基类上的虚拟析构函数,否则可能会发生错误:)
#include <string>
// Trivial base class so we can use polymorphism
class StoreItemsBase
{
public:
StoreItemsBase() {}
virtual ~StoreItemsBase() {}
};
template <typename TYPE> class arg_type
{
public:
typedef const TYPE& type;
};
template <typename TYPE> class arg_type<const TYPE*>
{
public:
typedef const TYPE* type;
};
// Example of a trivial Templated class to hold some 3 items.
// Intent to have similar classes to hold 4,5..n items
template <typename T1, typename T2, typename T3>
class Store3Items : public StoreItemsBase
{
typedef typename arg_type<T1>::type arg1;
typedef typename arg_type<T2>::type arg2;
typedef typename arg_type<T3>::type arg3;
public:
Store3Items(arg1 t1, arg2 t2, arg3 t3)
:
StoreItemsBase(),
mT1(t1),
mT2(t2),
mT3(t3)
{}
private:
T1 mT1;
T2 mT2;
T3 mT3;
};
// Function to create a pointer to our object with added id
// There would be similar CreateHolderFunctions for 4,5..n items
template <typename T1, typename T2, typename T3>
StoreItemsBase* CreateHolder(const T1 t1, const T2 t2, const T3 t3)
{
return new Store3Items<T1, T2, T3>(t1, t2, t3);
}
int main()
{
int testInt=3;
double testDouble=23.4;
const std::string testStr("Hello World");
StoreItemsBase* Ok1 = CreateHolder(testInt, testDouble, testStr);
StoreItemsBase* Ok2 = CreateHolder(testDouble, testStr, testInt);
StoreItemsBase* Ok3 = CreateHolder(testStr, static_cast<const char*>("Hello there"), testInt);
// If you try a standard string, it compiler complains
// Although I could surround all my strings with the static cast, what I am looking for is a way
// to for the CreateHolder function to do the work for me
StoreItemsBase* NotOk4 = CreateHolder(testStr, "Hello World", testInt);
// Free our objects not shown in the example
}
请记住,您的类将在内部存储原始const char *(不存储std :: string),因此请确保传入的字符串的范围将比您存储的指针更长。像你的例子中的常量字符串很好,因为它们永远存在。