有这么一串模板类继承自另一个模板类的代码,在 VS 中编译通过,但是在 Linux 使用 g++ 编译时报错

1
2
3
error: class 'InputChannel<channel>' does not have any field named 'IOChannelInterface'
error: 'channelName' was not declared in this scope
error: 'data' was not declared in this scope

似乎识别不出来 IOChannelInterface<channel> 这个类及其成员。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename channel>
struct IOChannelInterface : sc_module
{
string channelName;
sc_in<channel *> data;

IOChannelInterface(const string &name)
: channelName(name)
{
}
};

template <typename channel>
struct InputChannel : IOChannelInterface<channel>
{
InputChannel(const string &name) : IOChannelInterface(name)
{
}
};

当编译器遇到:

1
2
template <typename channel>
struct InputChannel : public IOChannelInterface<channel>

它并不知道 IOChannelInterface<channel> 是什么类型(因为 channel),更不知道它有没有一个 channelName 成员(可能会被特化,而这个特化里面没有 channelName 这个成员),直到最后 channel 被具象化才能确定。

解决办法:

  1. 子类加入父类成员变量的声明:

    1
    2
    using IOChannelInterface<channel>::channelName;
    using IOChannelInterface<channel>::data;
  2. 使用 this 指针引用成员

  3. 加上父类名 IOChannelInterface<channel>::channelName 来引用成员


正确的版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename channel>
struct IOChannelInterface : sc_module
{
string channelName;
sc_in<channel *> data;

IOChannelInterface(const string &name)
: channelName(name)
{
}
};

template <typename channel>
struct InputChannel : IOChannelInterface<channel>
{
using IOChannelInterface<channel>::channelName;
using IOChannelInterface<channel>::data;

InputChannel(const string &name)
: IOChannelInterface<channel>::IOChannelInterface(name)
{
}
};