我正在编写自定义惰性字符串类。
template <typename charT, typename traits = std::char_traits<charT>>
class lazy_basic_string
{
class char_proxy
{
char_proxy& operator=(charT ch);
};
char_proxy operator[](size_type i);
}
然后我想在类声明之外定义这些方法。
template <typename charT, typename traits>
using char_proxy = typename lazy_basic_string<charT, traits>::char_proxy;
template <typename charT, typename traits>
char_proxy<charT, traits>& char_proxy<charT, traits>::operator=(charT ch)
{
...
}
但我得到编译错误:
无法定义依赖 typedef char_proxy 的成员
所以我无法弄清楚这里出了什么问题。
为什么编译器不能使用快捷方式 char_proxy 而不是 lazy_basic_string::char_proxy ?
标准似乎没有特别明确地规定这一点。我能得到的最接近的是[温度等级]:
3 - 当成员函数、成员类、成员枚举、静态数据成员或成员
类模板的模板是在类模板定义之外定义的,成员定义是
定义为模板定义,其中模板参数是类模板的那些。这
成员定义中使用的模板参数名称可能与模板不同
类模板定义中使用的参数名称。类后面的模板参数列表
成员定义中的模板名称应按照与在成员定义中使用的顺序相同的顺序来命名参数。
成员的模板参数列表。 [...]
这意味着,尽管没有明确说明,外线类模板成员定义应该通过名称引用类模板,而不是通过别名模板。
应该很容易理解为什么这是必要的;由于别名模板可能导致任意复杂的计算,为了将类模板成员的使用与潜在的定义相匹配,编译器必须对别名模板参数的每种可能的组合执行该计算:
template<class T> struct S { void f(); };
template<class T> using s_t = std::conditional_t<sizeof(T) % 8 == 0,
S<T>, S<T*>>;
template<class T> void s_t<T>::f() {}
int main() { S<int> s; s.f(); } // defined?
有趣的是,clang(3.7)允许在类模板成员定义中使用别名模板,但仅限于直接身份计算:
template<class> struct T { void f(); };
template<class C> using id_t = C;
template<class C> using t_t = T<id_t<C>>;
template<class C> void t_t<C>::f() {} // OK??
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)