Dav*_*one 9 c++ templates template-specialization template-meta-programming c++11
我专注std::common_type于我的类型.我定义了以下专业:
common_type<my_type, my_type>
Run Code Online (Sandbox Code Playgroud)
一切都很好.然后有人来了并打电话std::common_type<my_type, my_type &>.如果传递引用而不是引用(因为它调用std::decay类型),则默认版本的行为相同.但是,它并不遵循std::common_type我需要正确工作的非参考版本.有没有比这样做更好的方法(为了简单起见,省略了对const的rvalue-reference):
common_type<my_type, my_type>
common_type<my_type, my_type &>
common_type<my_type, my_type const &>
common_type<my_type, my_type volatile &>
common_type<my_type, my_type const volatile &>
common_type<my_type, my_type &&>
common_type<my_type, my_type volatile &&>
common_type<my_type &, my_type>
common_type<my_type const &, my_type>
common_type<my_type volatile &, my_type>
common_type<my_type const volatile &, my_type>
common_type<my_type &&, my_type>
common_type<my_type volatile &&, my_type>
common_type<my_type &, my_type &>
common_type<my_type &, my_type const &>
common_type<my_type &, my_type volatile &>
...
Run Code Online (Sandbox Code Playgroud)
当然有更好的方法吗?根据我的统计,如果我们忽略const &&和那就是49种可能的版本const volatile &&
注意:my_type实际上是一个类模板本身,所以specialize实际上看起来更像
template<intmax_t lhs_min, intmax_t lhs_max, intmax_t rhs_min, intmax_t rhs_max>
class common_type<my_type<lhs_min, lhs_max>, my_type<rhs_min, rhs_max>>
Run Code Online (Sandbox Code Playgroud)
结果在哪里 my_type<min(lhs_min, rhs_min), max(lhs_max, rhs_max)>
如果我完全控制主要模板定义,解决方案将非常简单,但我显然无法改变std::common_type.
据我所知,您不需要完全专门化二进制的两侧common_type。这允许将一侧的专业数量减少到 12 个。my_type如果您只需要和的特化之间的通用类型my_type,那么专门化一侧就足够了。否则,您必须在右侧克隆它们,从而产生 24 个专业化。
struct my_type;
struct unique_t;
#include <type_traits>
template<class L, class R, class = void>
struct mytype_common_type
{
// not many specializations are required here,
// as you can use std::decay and don't have to use "Exact Matches"
using type = unique_t;
};
namespace std
{
template<class T> struct common_type<my_type, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type const, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type volatile, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type const volatile, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type const&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type volatile&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type const volatile&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type&&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type const&&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type volatile&&, T>
: mytype_common_type<my_type, T> {};
template<class T> struct common_type<my_type const volatile&&, T>
: mytype_common_type<my_type, T> {};
}
template<class T>
using Decay = typename std::decay<T>::type;
int main()
{
static_assert(std::is_same<unique_t,
std::common_type<my_type const volatile&&, int>::type
>{}, "!");
}
Run Code Online (Sandbox Code Playgroud)