根据模板参数声明成员或不声明成员

17

是否可以根据模板条件而不使用虚假空类型来声明或不声明成员变量?

例如:

struct empty{};
struct real_type{};

template<bool condition>
struct foo
{
    typename std::conditional<condition, real_type, empty>::type _member;
};
2个回答

16

您可以从具有专业化的模板中进行派生:

struct real_type { };

template<bool c>
struct foo_base { };

template<>
struct foo_base<true>
{
    real_type _member;
};

template<bool condition>
struct foo : foo_base<condition>
{
};

作为一个小测试:

int main()
{
    foo<true> t;
    t._member.x = 42; // OK

    foo<false> f;
    f._member.x = 42; // ERROR! No _member exists
}

太好了!这样当条件为假时,我的类中就不会有“空”结构体了。 - Mircea Ispas
@Felics 你只是在用一种空值替换另一种。不确定为什么你会关心一个空的 struct 成员变量,但无论如何... - Nik Bougalis
@NikBougalis 不完全是这样。当派生空结构体时,可能会被优化为真正的空结构体,但成员必须具有不同的地址,不能是“空”的。此外,最好不要有一个会污染名称空间的成员,而是有一个虚拟成员。这是为了启用/禁用一些功能,并考虑到我有很多功能,只需设置一些布尔模板参数即可获得任何组合,而无需编写组合数量的类。 - Mircea Ispas
遗憾的是,您不能将“裸露”的标识符传递给模板,因此我们无法编写 template<typename T, identifier X, bool b> struct maybe_member {}; template<typename T, identifier X> struct maybe_member<T,X,true> {T X;};。我们能做的最好的办法是使用类型标签,这会引入一种奇怪的语法和“成员”访问的样板代码。 - Yakk - Adam Nevraumont
@Felics 我并不反对。我只是认为你可能在担心一个没有安全保障的第三层排气口,而前门几乎肯定是开着的。 - Nik Bougalis
显示剩余3条评论

1

如果不使用虚拟空类型,是否可以根据模板条件声明或不声明成员变量?

我认为您也可以在不继承的情况下特化。这在-std=c++03-std=c++11下都经过了测试。

template<bool condition>
struct foo;

template<>
struct foo<true>
{
    real_type _member;
};

template<>
struct foo<false>
{
};

如果C++委员会给了我们想要/需要的东西,那就太好了:

template<bool condition>
struct foo
{
#if (condition == true)
    real_type _member;
#endif
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接