假设我定义了一个T使用模板参数的嵌套类的模板P,如下所示:
template<class P> class T
{
public:
T(P& p) : p(p) {}
P& p;
typename P::Nested& get_nested() { return p.nested; }
};
Run Code Online (Sandbox Code Playgroud)
如果我声明一个A包含一个名为的嵌套类的类Nested,我可以定义一个T<A>没有问题的类型的变量:
class A
{
public:
class Nested
{
public:
int i;
};
Nested nested;
};
void test2a()
{
A a;
a.nested.i = 1;
T<A> t_a(a);
t_a.get_nested().i = 2;
}
Run Code Online (Sandbox Code Playgroud)
现在,我想声明一个类B,以同样的方式,包含一个名为的嵌套类,Nested并继承自T<B>,如下所示:
class B : public T<B>
{
public:
class Nested
{
public:
int i;
};
Nested nested;
};
Run Code Online (Sandbox Code Playgroud)
编译上面的代码失败并出现错误:" 嵌套不是B的成员"
我想我理解发生了什么:在输入模板时,由于继承,B类未完全定义.
但是,我想知道是否有办法做这样的事情......
感谢帮助.
您需要推迟返回类型的分辨率,get_nested直到它被调用.
一种方法是使返回类型依赖于模板参数:
template<typename unused = void>
typename std::conditional<false, unused, P>::type::Nested&
get_nested() { return p.nested; }
Run Code Online (Sandbox Code Playgroud)
另一种方式(自C++ 14以来)是使用返回类型推导:
auto& get_nested() { return p.nested; }
Run Code Online (Sandbox Code Playgroud)
我可以简单地编译你的示例
template<class P> class T
{
public:
T(P& p) : p(p) {}
P& p;
auto& get_nested() { return p.nested; }
};
Run Code Online (Sandbox Code Playgroud)
另一种方法,利用与@ecatmur相同的技巧,但更简单一些:
template<class R = P>
typename R::Nested& get_nested() { return p.nested; }
Run Code Online (Sandbox Code Playgroud)
同样,这里编译器必须推迟对 的求值,P::Nested直到您调用get_nested().
| 归档时间: |
|
| 查看次数: |
390 次 |
| 最近记录: |