0

The following should, I believe, compile and link, but doesn't:

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; }          

The compiler output:

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;

If I remove the __restrict__ qualifier in both places, it does compile and link. What am I doing wrong?

Notes:

  • This is the only question on SO (as of the time of writing) regarding both the restrict qualifier and templates. Funny, isn't it?
  • I'm using GCC 4.9.3 with --std=c++11.
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • What is the compilers error? – tahsmith Mar 06 '16 at 23:20
  • "What am I doing wrong?" Expecting compiler extention bringing features from another language to flawlesly integrate with C++specific features – Revolver_Ocelot Mar 06 '16 at 23:24
  • @Revolver_Ocelot: But `restrict` is very important... it's not an obscure nice-to-have feature. – einpoklum Mar 06 '16 at 23:26
  • @tahsmith: See edit. – einpoklum Mar 06 '16 at 23:29
  • 1
    @einpoklum it doesn't matter how it is important. It is non-standard (yet). Most compilers have own limited and incompatible implementation. GCC explicitely states that it brough C99 restrict. This means that it is valid everywhere it would be valid in C (and explicitely as member function qualifier). Function overloading and templates are not from C and nowhere in documentaion is said that restrict is supported in such cases. – Revolver_Ocelot Mar 06 '16 at 23:32
  • @Revolver_Ocelot: Fair enough. – einpoklum Mar 07 '16 at 00:21

1 Answers1

1

The __restrict__ keyword does not seem to really create a new type:

As with all outermost parameter qualifiers, __restrict__ is ignored in function definition matching. This means you only need to specify __restrict__ in a function definition, rather than in a function prototype as well.

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

Removing __restrict__ in the template parameter and the pure virtual function definition while leaving it in the function definition itself seems to achieve what you want, though.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
tahsmith
  • 1,643
  • 1
  • 17
  • 23