gpt4 book ai didi

c++ - 在 base-clause 中使用类内定义的类型定义/类型别名

转载 作者:行者123 更新时间:2023-11-28 05:55:32 25 4
gpt4 key购买 nike

我经常面临类定义中不可避免的代码重复问题,即我在 base-clause 中键入 base-specifiers,然后我应该为每个非默认构造的 base 再键入/复制至少一次相同的代码: 在构造函数中(在成员初始值设定项列表或其主体中)。将其中一些输入两次是很烦人的事情。我看到了问题的解决方案:允许用户在 typedef 的基本子句中使用,类型别名和在当前类范围内定义的别名模板。 IE。在其定义之前,因为它允许在当前类范围内定义其他符号(数据成员、成员函数)。

C++ 是否存在任何 C++ 固有的限制,以允许向前使用在类作用域中定义的类型定义/类型别名/别名模板?

例如:

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);

but I don't want to repeat the template arguments...

那么恐怕我们不得不求助于宏:

#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

关于c++ - 在 base-clause 中使用类内定义的类型定义/类型别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34242980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com