限制指针类型模板参数和覆盖模板基类的虚拟方法

Posted

技术标签:

【中文标题】限制指针类型模板参数和覆盖模板基类的虚拟方法【英文标题】:restrict-pointer-type template arguments and overriding virtual methods of a templated base class 【发布时间】:2016-03-06 23:10:32 【问题描述】:

我相信,以下内容应该编译和链接,但不是:

template<class S>
class A 
public:
    virtual int foo(S arg) = 0;
    virtual ~A()  
;

class B : public A<int* __restrict__>

public:
    int foo(int* __restrict__  arg) override  return 0; 
;

int main()  B b;           

编译器输出:

d9.cpp:11:6: error: ‘int B::foo(int*)’ marked override, but does not override
  int foo(int* __restrict__  arg) override  return 0; 
      ^
d9.cpp: In function ‘int main()’:
d9.cpp:14:16: error: cannot declare variable ‘b’ to be of abstract type ‘B’
 int main()  B b; 
                ^
d9.cpp:8:7: note:   because the following virtual functions are pure within ‘B’:
 class B : public A<int* __restrict__>
       ^
d9.cpp:4:14: note:  int A<S>::foo(S) [with S = int* __restrict__]
  virtual int foo(S arg) = 0;

如果我在两个地方都删除了__restrict__ 限定符,它会编译并链接。我做错了什么?

注意事项:

这是关于限制限定符和模板的关于 SO(截至撰写本文时)的唯一问题。很有趣,不是吗? 我正在使用 GCC 4.9.3 和 --std=c++11

【问题讨论】:

编译器错误是什么? “我做错了什么?”期望编译器扩展将另一种语言的功能与 C++ 特定功能完美集成 @Revolver_Ocelot:但restrict 非常重要……它不是一个不起眼的好功能。 @tahsmith:见编辑。 @einpoklum 它有多重要并不重要。它是非标准的(还)。大多数编译器都有自己有限且不兼容的实现。 GCC 明确声明它带来了 C99 限制。这意味着它在 C 中有效的任何地方都有效(并且明确地作为成员函数限定符)。函数重载和模板不是来自 C 语言,并且在文档中没有任何地方说在这种情况下支持限制。 【参考方案1】:

__restrict__ 关键字似乎并没有真正创建新类型:

与所有最外层的参数限定符一样,__restrict__ 在 函数定义匹配。这意味着您只需要指定 __restrict__ 在函数定义中,而不是在函数原型中。

https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html

在模板参数和纯虚函数定义中删除__restrict__,而将其保留在函数定义本身中似乎可以实现您想要的。

【讨论】:

以上是关于限制指针类型模板参数和覆盖模板基类的虚拟方法的主要内容,如果未能解决你的问题,请参考以下文章

我无法覆盖基类的方法,因为我的派生类是模板化的

在模板基类中为继承类中的可选覆盖生成虚拟方法

模板化函数或带有指向基类的指针的函数

包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数

C++ 派生模板类:访问实例的受保护成员

根据 Derived 中的值检查基类的模板参数