【发布时间】:2020-03-04 12:12:05
【问题描述】:
我有一些字符串类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!");
}
我现在得到的 GCC 错误:
UnderlyingTemplateType.cpp:9:30: error: expected nested-name-specifier before 'CharType'
using ValueType = typename CharType;
但是当我删除 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)
如何正确地做到这一点?我想使用IMyString::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
}
是否有一个简洁的定义允许ValueType 充当真实类型?
【问题讨论】:
-
错误告诉你写的是
const typename StringType::ValueType* dataToAdd,因为此时StringType对解析器是不透明的。 -
@Quentin 可以通过不同地定义 ValueType 以某种方式避免该要求吗?每次使用都必须写 typename 看起来很烦人,也让人分心,因为它在变量名中并不常见。
-
否,但您可以定义
template <class StringType> using ValueType = typename StringType::ValueType,然后在您的代码中使用ValueType<StringType>。 -
做错误所说的事情...?
-
@TomášZato-ReinstateMonica 在 blockscope 中你可以定义一个新的别名。在您的示例中,您可以使用第二个模板参数
typename ValueType = typename StringType::ValueType。