无法使用 auto 和 decltype() 时如何避免重复封闭的 class 类型
How to avoid repetition of the enclosing class type when auto and decltype() cannot be used
我最近发现了 C++11 的 auto
和 decltype()
特性,它们非常棒,因为它们可以消除大量冗余类型代码。但是,在某些情况下不能使用它们。我主要问的一个例子是,如果你想直接或作为模板参数声明一个类型使用封闭 class 类型的变量,并且你没有初始化表达式(这将有允许您使用 auto
)。如果封闭的 class 类型是具有许多模板参数的模板 class,这尤其不可取。例如:
template<typename T1, typename T2, typename T3, typename T4, typename T5 > struct S {
std::map<int,S<T1,T2,T3,T4,T5>*> m1;
std::map<int,S<T1,T2,T3,T4,T5>*> m2;
std::map<int,S<T1,T2,T3,T4,T5>*> m3;
std::map<int,S<T1,T2,T3,T4,T5>*> m4;
std::map<int,S<T1,T2,T3,T4,T5>*> m5;
};
合理的解决方案是使用 typedef:
template<typename T1, typename T2, typename T3, typename T4, typename T5 > struct S {
typedef S<T1,T2,T3,T4,T5> ThisClass;
std::map<int,ThisClass*> m1;
std::map<int,ThisClass*> m2;
std::map<int,ThisClass*> m3;
std::map<int,ThisClass*> m4;
std::map<int,ThisClass*> m5;
};
但是,必须声明一个只重复封闭 class 类型的 typedef 仍然是不可取的。
如果你在实例方法中,这实际上可以通过推导 *this
的类型来解决,尽管必要的代码比我想要的更冗长:
auto copy(void) {
typename std::remove_reference<decltype(*this)>::type s = *this;
// ... do stuff with s ...
return s;
}
此解决方案在 class 范围内不起作用,因为 this
是不允许的,并且在实例方法之外没有意义(编译器抱怨 "invalid use of ‘this’ at top level"
)。
所以,我的问题是,当你不能使用 auto
或 decltype()
时,推荐的解决方案是什么,以避免重复封闭 class 的类型,当你必须在 class 定义中使用它吗? typedef 是唯一的选择吗?
如果您指的是当前实例化,则无需重复模板参数。
template<typename T1, typename T2, typename T3, typename T4, typename T5 > struct S {
std::map<int,S*> m1;
std::map<int,S*> m2;
std::map<int,S*> m3;
std::map<int,S*> m4;
std::map<int,S*> m5;
};
injected-class-name S
指的是当前实例化,在本例中是S<T1, T2, T3, T4, T5>
.
我最近发现了 C++11 的 auto
和 decltype()
特性,它们非常棒,因为它们可以消除大量冗余类型代码。但是,在某些情况下不能使用它们。我主要问的一个例子是,如果你想直接或作为模板参数声明一个类型使用封闭 class 类型的变量,并且你没有初始化表达式(这将有允许您使用 auto
)。如果封闭的 class 类型是具有许多模板参数的模板 class,这尤其不可取。例如:
template<typename T1, typename T2, typename T3, typename T4, typename T5 > struct S {
std::map<int,S<T1,T2,T3,T4,T5>*> m1;
std::map<int,S<T1,T2,T3,T4,T5>*> m2;
std::map<int,S<T1,T2,T3,T4,T5>*> m3;
std::map<int,S<T1,T2,T3,T4,T5>*> m4;
std::map<int,S<T1,T2,T3,T4,T5>*> m5;
};
合理的解决方案是使用 typedef:
template<typename T1, typename T2, typename T3, typename T4, typename T5 > struct S {
typedef S<T1,T2,T3,T4,T5> ThisClass;
std::map<int,ThisClass*> m1;
std::map<int,ThisClass*> m2;
std::map<int,ThisClass*> m3;
std::map<int,ThisClass*> m4;
std::map<int,ThisClass*> m5;
};
但是,必须声明一个只重复封闭 class 类型的 typedef 仍然是不可取的。
如果你在实例方法中,这实际上可以通过推导 *this
的类型来解决,尽管必要的代码比我想要的更冗长:
auto copy(void) {
typename std::remove_reference<decltype(*this)>::type s = *this;
// ... do stuff with s ...
return s;
}
此解决方案在 class 范围内不起作用,因为 this
是不允许的,并且在实例方法之外没有意义(编译器抱怨 "invalid use of ‘this’ at top level"
)。
所以,我的问题是,当你不能使用 auto
或 decltype()
时,推荐的解决方案是什么,以避免重复封闭 class 的类型,当你必须在 class 定义中使用它吗? typedef 是唯一的选择吗?
如果您指的是当前实例化,则无需重复模板参数。
template<typename T1, typename T2, typename T3, typename T4, typename T5 > struct S {
std::map<int,S*> m1;
std::map<int,S*> m2;
std::map<int,S*> m3;
std::map<int,S*> m4;
std::map<int,S*> m5;
};
injected-class-name S
指的是当前实例化,在本例中是S<T1, T2, T3, T4, T5>
.