在基类子句中使用类中定义的typedefs/type别名
Using in-class defined typedefs/type aliases in base-clause
我经常在类定义中面临不可避免的代码重复问题,即我在base子句中键入基说明符,然后我应该为每个非默认构造的基至少再键入/复制一次相同的代码:在构造函数中(在成员初始值设定项列表或其主体中)。有些打字打两次是件烦人的事。我看到了这个问题的解决方案:允许用户使用在当前类作用域中定义的typedefs、类型别名和别名模板的基本子句。即在定义之前,因为它允许在当前类范围内定义其他符号(数据成员、成员函数)。
是否存在C++-C++性质所施加的任何固有限制,以允许在类范围中定义的typedefs/类型别名/别名模板的前向使用?
例如:
template< bool >
struct enable_default_constructor;
template<>
struct enable_default_constructor< true >
{
enable_default_constructor() = default;
enable_default_constructor(void * ) { ; }
};
template<>
struct enable_default_constructor< false >
{
enable_default_constructor() = delete;
enable_default_constructor(void * ) { ; }
};
template< typename ...Ts >
struct X
: enable_default_constructor< (std::is_default_constructible< Ts >::value && ...) >
{
// next line containing duplication of code
using enabler = enable_default_constructor< (std::is_default_constructible< Ts >::value && ...) >;
X() = default;
template< typename ...Us >
X(Us &&... v)
: enabler({})
, m(std::forward< Us >(v)...) // using symbol `m` before definition
{ ; }
private :
std::tuple< Ts... > m;
};
struct S {};
struct N { N() = delete; };
static_assert(std::is_default_constructible< X< int, double, S > >::value);
static_assert(!std::is_default_constructible< X< int, double, N > >::value);
我想直接在基子句中使用enabler
符号。
如果我的想法是正确的,你想避免写基类的名称(例如,因为它是一个长而复杂的模板),那么有一种稍微复杂的方法。
将此应用于您的上述要求:
template< bool >
struct enable_default_constructor;
template<>
struct enable_default_constructor< true >
{
enable_default_constructor() = default;
enable_default_constructor(void * ) { ; }
};
template<>
struct enable_default_constructor< false >
{
enable_default_constructor() = delete;
enable_default_constructor(void * ) { ; }
};
namespace declare_X
{
template<typename ...Ts> using
base = ::enable_default_constructor< (std::is_default_constructible< Ts >::value && ...) >;
template< typename ...Ts >
struct X
: base<Ts...>
{
X() = default;
X(Ts &&... v)
: base<Ts...>({})
, m(std::forward< Ts >(v)...)
{ ; }
private :
std::tuple< Ts... > m;
};
}
template<typename...Ts> using X = declare_X::X<Ts...>;
struct S {};
struct N { N() = delete; };
static_assert(std::is_default_constructible< X< int, double, S > >::value);
static_assert(!std::is_default_constructible< X< int, double, N > >::value);
但我不想重复模板的论点。。。
那么恐怕我们不得不求助于宏:
#if defined(BASE_CLASS)
#undef BASE_CLASS
#endif
#define BASE_CLASS enable_default_constructor< (std::is_default_constructible< Ts >::value && ...) >
template< typename ...Ts >
struct X
: BASE_CLASS
{
X() = default;
X(Ts &&... v)
: BASE_CLASS({})
, m(std::forward< Ts >(v)...)
{ ; }
private :
std::tuple< Ts... > m;
};
#undef BASE_CLASS
只需对类模板定义进行一点修改,就可以将繁重的类型粘贴到模板参数列表中:
namespace internal
{
template <typename, typename> struct XImpl;
template <typename ...Args, typename Enabler>
struct XImpl<std::tuple<Args...>, Enabler> : Enabler
{
using XImpl() = default;
// ...
};
}
template <typename ...Args>
using X = internal::XImpl<std::tuple<Args...>,
HorrendousEnablerTemplate<Args...>>;
相关文章:
- 在提升multi_index容器中,是否定义了"default index"?
- #定义c-预处理器常量..我做错了什么
- 用C++中的一个变量定义一个常量
- 部分定义/别名模板模板参数
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- #为""定义宏;静态";针对不同的上下文
- 如何确保C++函数在定义之前声明(如override关键字)
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在命名空间中定义函数还是限定函数
- 此代码是否违反一个定义规则
- 编译C++时未定义的引用
- 不同翻译单元中不可重载的非内联函数定义
- 为什么在定义函数之前先声明它
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 在类定义之后定义一个私有方法
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- 如何定义 typedefs 的隐式转换?
- 在基类子句中使用类中定义的typedefs/type别名