使用VS公共继承模板化

templated using VS public inheritance

本文关键字:继承 VS 使用      更新时间:2023-10-16

我相信添加using关键字是为了允许模板类型定义。然而,我遇到了一个编译错误,这里是简化的代码:

template <bool EnableFirst, class T1, class T2>
struct OneOfTwo {};
template <class T1, class T2>
struct OneOfTwo<true, T1, T2>
{
using type = T1;
};
template <class T1, class T2>
struct OneOfTwo<false, T1, T2>
{
using type = T2;
};
struct A
{
static constexpr int X = 1;
};
struct B
{
static constexpr int X = 12;
};
struct C {};
struct D {};
template <class T1, class T2>
using ClassX = OneOfTwo<T1::X == T2::X, C, D>::type;            //C4346: 'T2::X': dependent name is not a type;  C2061: syntax error: identifier 'type'
template <class T1, class T2>
struct ClassY : public OneOfTwo<T1::X == T2::X, C, D>::type {}; //OK

我这样使用这些类:

ClassY<A, B> y;
ClassX<A, B> x;

我认为ClassXClassY应该是完全一样的东西,但是ClassX会导致编译错误。所以我的问题是:我打破了C++标准的哪一部分?

顺便说一句,我使用的是支持XP的MSVC 2015工具集(v140_XP)。

您缺少一个typename关键字:

template <class T1, class T2>
using ClassX = typename OneOfTwo<T1::X == T2::X, C, D>::type;

using关键字在其定义中需要类型

using ABC = SomeClass;

ABC不是类型,它是类型别名(也称为typename)。。。

所以,这条线失败了:

using ClassX = OneOfTwo<T1::X == T2::X, C, D>::type;

C4346:'T2::X':依赖名称不是类型;C2061:语法错误:标识符"type">

此错误的更准确表示为:

错误:typename不是class。。。

typename是类型别名的说明符,可以是任何,从ints到void*s到任何。。。但一个阶级有它自己的身份。。。这是一个。。。

因此,为了修复您的错误,您必须在类型别名之前指定typename。。。

// Adding the 'typename' keyword is also needed for nested classes, according to YSC
using ClassX = typename OneOfTwo<T1::X == T2::X, C, D>::type;

阅读:键入别名


编辑:这样做也会产生相同的结果:

template <class T1, class T2>
struct OneOfTwo<false, T1, T2>
{
typedef T2 type;
}

不过,在typedef中,您不能像使用using那样创建类型别名的别名,因此using具有优势。。。

注意:根据建议:添加"typename"被认为是多余的,因为C++20…