C++ 如何正确公开要用作类型的基础模板类型
我有一些字符串类C++ 如何正确公开要用作类型的基础模板类型,c++,c++11,templates,using,C++,C++11,Templates,Using,我有一些字符串类IMyString,可以是wstring或普通字符串。它有两个派生词MyString和MWString。如果模板化代码希望同时接受这两个参数,则当前需要字符串类型参数和字符类型参数。我想改变这一点 这是我的代码: // This string doesn't work, it's just an example template <typename CharType, typename Derived> class IMyString { public: // D
IMyString
,可以是wstring或普通字符串。它有两个派生词MyString
和MWString
。如果模板化代码希望同时接受这两个参数,则当前需要字符串类型参数和字符类型参数。我想改变这一点
这是我的代码:
// This string doesn't work, it's just an example
template <typename CharType, typename Derived>
class IMyString
{
public:
// Define value type so that it can ba accessed by other templates (does not work)
using ValueType = typename CharType;
const CharType* c_str() const { return rawData; }
// Does not actually do the adition for brevity, just imagine it instead
Derived&& operator+(const CharType* moreData) const { return Derived(/*should add my own data here and also copy everything etc*/moreData); }
protected:
IMyString(const CharType* rawData) : rawData(rawData) {}
const CharType* rawData = nullptr;
};
// Normal string
class MyString : public IMyString<char, MyString>
{
public:
MyString(const char* data) : IMyString(data) {}
};
// Wide char string
class MyWString : public IMyString<wchar_t, MyString>
{
public:
MyWString(const wchar_t* data) : IMyString(data) {}
};
// Method that doesn't really do anything actually
template <typename StringType>
// I want to be able to use the value type directly as type
void DoSomethingWithAnyString(StringType string, const StringType::ValueType* dataToAdd)
{
StringType string2 = string + dataToAdd;
// even if the addition worked, it has no effect because the value is not returned
}
int main()
{
MyString someString("Hello");
DoSomethingWithAnyString(someString, " world!");
}
但当我删除typename时,这也是一个错误:
UnderlyingTemplateType.cpp:40:56: error: need 'typename' before 'StringType::ValueType' because 'StringType' is a dependent scope
void DoSomethingWithAnyString(StringType string, const StringType::ValueType* dataToAdd)
如何正确地做到这一点?我想像使用嵌套类/struct/enum一样使用imysting::ValueType
我可以看出这是可行的,但我不想在使用ValueType
的任何地方都写typename
:
// Method that doesn't really do anything actually
template <typename StringType>
// I want to be able to use the value type directly as type
void DoSomethingWithAnyString(StringType string, const typename StringType::ValueType* dataToAdd)
{
StringType string2 = string + dataToAdd;
// even if the addition worked, it has no effect because the value is not returned
}
//实际上什么都不做的方法
模板
//我希望能够将值类型直接用作类型
void DoSomethingWithAnyString(StringType字符串,常量类型名称StringType::ValueType*dataToAdd)
{
StringType string2=字符串+数据添加;
//即使加法有效,也没有效果,因为没有返回值
}
是否有一个简明的定义允许
ValueType
充当一个真正的类型?您能做的最好的事情就是这样——编写一个帮助器别名来包装被轻视的类型名
模板
使用char\u t=typename t::ValueType;
//方法,实际上什么都不做
模板
//我希望能够将值类型直接用作类型
void DoSomethingWithAnyString(StringType字符串,常量字符*数据添加)
{
StringType string2=字符串+数据添加;
//即使加法有效,也没有效果,因为没有返回值
}
您所能做的最好的事情就是这样——编写一个帮助器别名来包装被轻视的类型名
模板
使用char\u t=typename t::ValueType;
//方法,实际上什么都不做
模板
//我希望能够将值类型直接用作类型
void DoSomethingWithAnyString(StringType字符串,常量字符*数据添加)
{
StringType string2=字符串+数据添加;
//即使加法有效,也没有效果,因为没有返回值
}
错误告诉您要写的是const-typename-StringType::ValueType*dataToAdd
,因为StringType
对解析器来说是不透明的。@Quentin可以通过不同的定义ValueType来避免这种要求吗?每次使用时都要写typename似乎很烦人,也会让人分心,因为这在变量名中并不常见。不,但您可以使用ValueType=typename StringType::ValueType定义模板,然后在代码中使用ValueType
。执行错误显示的两项操作…?@TomášZato在blockscope中可以定义新别名。在您的示例中,可以使用第二个模板参数typename ValueType=typename StringType::ValueType
。错误告诉您要编写的是const typename StringType::ValueType*dataToAdd
,因为StringType
在这一点上对解析器来说是不透明的。@Quentin可以通过不同的定义ValueType来避免这种要求吗?每次使用时都要写typename似乎很烦人,也会让人分心,因为这在变量名中并不常见。不,但您可以使用ValueType=typename StringType::ValueType定义模板,然后在代码中使用ValueType
。执行错误显示的两项操作…?@TomášZato在blockscope中可以定义新别名。在您的示例中,可以使用第二个模板参数typename ValueType=typename StringType::ValueType
。我试图在imysting
中直接执行类似操作,但仍然无法使用StringType::char\u type
。我很困惑,为什么有时候重复这个字体名是有效的,有时候却不行。@TomášZato,你只需要接受,所以标准说:
:P。更严重的是,在模板内部,你不能使用typename
,因为它不是独立的名称。yetI试图在imysting
中直接做类似的事情,但我仍然不能使用StringType::char\u type
。我很困惑,为什么有时候重复typename是有效的,有时候不是。@TomášZato,好吧,你只需要接受所以标准说eth
:P。更严重的是,在模板内部,你不能使用typename
,因为它还不是从属名称
// Method that doesn't really do anything actually
template <typename StringType>
// I want to be able to use the value type directly as type
void DoSomethingWithAnyString(StringType string, const typename StringType::ValueType* dataToAdd)
{
StringType string2 = string + dataToAdd;
// even if the addition worked, it has no effect because the value is not returned
}