1

我将从一些代码开始。考虑:

template <typename Message> void ProcessMessage (const Message& msg)
{
    const uint32_t value = msg.mValue.GetValAs <uint32_t>();
}

在这里,mValue不同类型的类型是不同的Message。它可能具有的所有类型都有一个成员模板函数GetValAs和一个成员mValue——这些都是不变的条件。 Message可能是这样的:

class Message16
{
public:
    Message16 (uint16_t value) : mValue (value) {}; 
    UInt16Field mValue;
};

UInt16Field类模板的具体实例在哪里。

或者它可能是:

class Message32
{
public:
    Message32 (uint32_t value) : mValue (value) {}; 
    std::string mFoo;
    double mBar;
    UInt32Field mValue;
};

UIInt32Field同一个类模板的另一个具体实例在哪里。

现在这里的问题是依赖名称的解析,特别是:

template <typename Message> void ProcessMessage (const Message& msg)
{
    const uint32_t value = msg.mValue.GetValAs <uint32_t>();
}

产生编译器错误:

main.cpp: In function ‘void ProcessMessage(const Message&)’:
main.cpp:60:57: error: expected primary-expression before ‘&gt;’ token
main.cpp:60:59: error: expected primary-expression before ‘)’ token

好的,这通常很简单......我只需使用this->orRealType::来解析依赖名称。例如:

    const uint32_t value = msg.mValue.UInt16Field::GetValAs <uint32_t>();
                                      ^^^^^^^^^^^^^

只要mValue始终是- 就可以正常工作UInt16Field- 但事实并非如此。它可以是(几乎)任何东西。如果我尝试ProcessMessage使用Message32例如调用:

const uint32_t u32 = 32;
Message32 msg32 (u32);
ProcessMessage (msg32);

我得到了一些预期的(当然不是很好)编译器错误:

error: ‘GetValAs<uint32_t>’ is not a member of ‘const UInt32Field {aka const IntegralField<unsigned int>}’

所以,问题是...

我怎样才能在这里引入依赖类型mValue

    const uint32_t value = msg.mValue.GetValAs <uint32_t>();

不使用this->(因为没有this)或RealType::(因为我不知道RealType)?


这是一个完整的测试平台,尽我所能:

template <typename IntegralType>
class BasicField
{
public:
    BasicField (IntegralType val) : mValue (val) {}
    IntegralType mValue;
};

template <typename IntegralType>
class IntegralField
:
    public BasicField <IntegralType>
{
public:
    IntegralField (IntegralType val)
    :
        BasicField <IntegralType> (val*2)
    {
    }

    IntegralType GetVal () const
    {
        return this->mValue/2;
    }

    operator IntegralType () const
    {
        return GetVal();
    }

    template <typename As> As GetValAs () const
    {
        return static_cast <As> (GetVal());
    }
};

typedef IntegralField <uint16_t> UInt16Field;
typedef IntegralField <uint32_t> UInt32Field;

class Message16
{
public:
    Message16 (uint16_t value) : mValue (value) {};
    UInt16Field mValue;
};

class Message32
{
public:
    Message32 (uint32_t value) : mValue (value) {};
    std::string mFoo;
    double mBar;
    UInt32Field mValue;
};

template <typename Message> void ProcessMessage (const Message& msg)
{
    const uint32_t value = msg.mValue.GetValAs <uint32_t>();
}

int main()
{
    const uint16_t u16 = 16;
    Message16 msg16 (u16);
    ProcessMessage (msg16);

    const uint32_t u32 = 32;
    Message32 msg32 (u32);
    ProcessMessage (msg32);

}
4

3 回答 3

4

您可能需要向GetValAs作为模板的编译器解释,尝试:

msg.mValue.template GetValAs<uint32_t>();
于 2013-10-30T17:57:58.827 回答
2

我认为您正在寻找的是:

 msg.mValue.template GetValAs <uint32_t>();

这就是语法。解释与 类似typename

结合typenametemplate,有时代码如下所示:

 using type = typename X<T>::template get<U>::type;

或者如果你使用 typedef,那么:

 typedef typename X<T>::template get<U>::type type;

我的代码中有这样的怪物。

于 2013-10-30T17:58:06.547 回答
2
const uint32_t value = msg.mValue.template GetValAs <uint32_t>();
                                  ^^^^^^^^

GetValAs是一个模板,编译器应该知道它。

于 2013-10-30T17:58:42.223 回答