C++ &引用;未在此范围内声明”;解析公共派生基类模板中函数模板的名称时出错

C++ &引用;未在此范围内声明”;解析公共派生基类模板中函数模板的名称时出错,c++,C++,考虑(): 我仍然得到: error: expected primary-expression before ‘>’ token On:returnmybase::ExtractAs() 编辑:以下是最终的工作代码: #include <cstdlib> #include <cassert> #include <stdint.h> #pragma pack (1) template <size_t Width> class Base {

考虑():

我仍然得到:

error: expected primary-expression before ‘>’ token
On:
returnmybase::ExtractAs()

编辑:以下是最终的工作代码:

#include <cstdlib>
#include <cassert>
#include <stdint.h>

#pragma pack (1)

template <size_t Width>
class Base
{
public:
    char mData [Width];
    template <typename Field> Field ExtractAs () const
    {
        return *reinterpret_cast <const Field*> (mData);
    }
};

template <typename FieldVal>
class IntegralField
:
    public Base <sizeof (FieldVal)>
{
public:
    FieldVal GetVal () const
    {
        return this->template ExtractAs<FieldVal>();
    }
};

int main()
{
    char raw[4] = {0x11, 0x22, 0x33, 0x44};
    typedef IntegralField <uint32_t> UInt32Field;
    const UInt32Field& field =
        *reinterpret_cast <const UInt32Field*> (raw);
    const uint32_t extracted = field.GetVal();
    assert (extracted == 0x44332211);
}
#包括
#包括
#包括
#布拉格语包(1)
模板
阶级基础
{
公众:
字符mData[宽度];
模板字段ExtractAs()常量
{
return*reinterpret_cast(mData);
}
};
模板
类积分域
:
公共基地
{
公众:
FieldVal GetVal()常量
{
返回此->模板ExtractAs();
}
};
int main()
{
charraw[4]={0x11、0x22、0x33、0x44};
类型定义整型字段UINT32字段;
const UINT32字段和字段=
*重新解释铸件(原始);
const uint32_t extracted=field.GetVal();
断言(提取==0x44332211);
}
您可以说:

return this->template ExtractAs<FieldVal>();
返回此->模板ExtractAs();

returnbase::template ExtractAs();
因为您在类模板中,并且基也是模板专用化,所以基成员的名称不会自动注入到派生模板中。(考虑一下如果您专门从事
Base
!)


通过限定名称或使用
this->
,可以使整个名称依赖,因此在第一阶段不会导致错误。此外,由于名称
ExtractAs
是依赖的(作为模板的嵌套名称),因此必须使用@AndreyT的建议逐字逐句地消除它作为
template

的歧义:
error:expected primary expression before'>'token
。我试图更加明确,但这仍然会产生错误。我在上面的原始帖子中编辑了这一尝试。使用
this->
变量会产生与我之前评论相同的编译器错误。@约翰迪布林您需要在该表达式中使用
template
消歧器--将其更改为
this->template ExtractAs()
typename Base::template ExtractAs()@0x499602D2:哇,是的。我几乎认为我应该需要它。修正@约翰迪布林:对不起,我来来去去。我真的应该更清楚这一点。我确实在某个时候广泛地写过这类东西。关键是
ExtractAs
是一个依赖名称,因此需要在值、类型和模板之间消除歧义。
  FieldVal GetVal () const
    {
        static const size_t fieldSize = sizeof (FieldVal);
        typedef Base <fieldSize> MyBase;
        typedef FieldVal MyField;
        return MyBase::ExtractAs <MyField> ();
    }
error: expected primary-expression before ‘>’ token
#include <cstdlib>
#include <cassert>
#include <stdint.h>

#pragma pack (1)

template <size_t Width>
class Base
{
public:
    char mData [Width];
    template <typename Field> Field ExtractAs () const
    {
        return *reinterpret_cast <const Field*> (mData);
    }
};

template <typename FieldVal>
class IntegralField
:
    public Base <sizeof (FieldVal)>
{
public:
    FieldVal GetVal () const
    {
        return this->template ExtractAs<FieldVal>();
    }
};

int main()
{
    char raw[4] = {0x11, 0x22, 0x33, 0x44};
    typedef IntegralField <uint32_t> UInt32Field;
    const UInt32Field& field =
        *reinterpret_cast <const UInt32Field*> (raw);
    const uint32_t extracted = field.GetVal();
    assert (extracted == 0x44332211);
}
return this->template ExtractAs<FieldVal>();
return Base<sizeof(FieldVal)>::template ExtractAs<FieldVal>();