Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

override specifier as template parameter - is it valid?

I have the following piece of code that does not compile under Visual C++ 2015, but does under GCC 4.8.4. I'm wondering which is right? The code in question is here below:

template <class T> class ATemplate;
template <class R, class A1>
    struct ATemplate<R(A1)>{ };

int main()
{
    ATemplate<void(int)> x;
//    ATemplate<void(int)override> y; //---Does not compile!!!
    return 0;
}

Is it wrong to use override as specifier here below (or const). Similar code exists in the GMock library, where macro expansion is used to generate the template parameter (including override), as well as the actual function signature.

Visual C++ 2015 produces the following error when removing the commented out line:

x.cpp(11): error C2062: type 'int' unexpected
x.cpp(11): error C2976: 'ATemplate': too few template arguments
x.cpp(4): note: see declaration of 'ATemplate'
x.cpp(11): error C2079: 'y' uses undefined class 'ATemplate'

One of the answers below mention that override is meaningless in the context of free functions (valid point) - does this mean GCC is wrong here. The const specifier is also meaningless in that case (for free functions), but nevertheless permitted (by VC++)??? Also, it mentions that virtual specifiers should only exists in the declaration - this makes no difference to this case (as no definition exists). For the virtual keyword, it is OK to ommit in the derived as it makes no difference to whether code compiles, but for the override case it is not OK as it makes a big difference.

When using ReturnType (ArgType arg) ...possible const or override specifier as a macro parameter (like GMock does), the restriction imposed by VCC causes this code not to compile (apparently the case for Clang too). Which is right?

The standard does not state that the override specifier shall not be used in this context (the context of a template parameter?), does it?

like image 527
Werner Erasmus Avatar asked Nov 02 '15 09:11

Werner Erasmus


People also ask

What can the template parameter in C++ template definition be?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.

How do you use template arguments in C++?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

What is Typename in C++ template?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.

What is non type template parameters?

A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type. A pointer or reference to a class object.


2 Answers

It's a g++ bug.

The standard permits virt-specifier-sec in two productions: in a function-definition (only for virtual member-function definitions) and in a member-declarator. Your context is neither.

A shorter demo of GCC's buggy behaviour:

void foo(void) override;          // g++ rejects with message: 
                                  //  virt-specifiers in 'foo' 
                                  //  not allowed outside a class definition
void (*bar)(void) override;       // g++ erroneously accepts
typedef void baz(void) override;  // g++ erroneously accepts
like image 65
n. 1.8e9-where's-my-share m. Avatar answered Oct 21 '22 18:10

n. 1.8e9-where's-my-share m.


According to the standard the override specifier is context-sensitive and has special meaning only when it's used after a member function declaration; otherwise, it's not a reserved keyword.

So i would say, the code in your second example seems meaningless.

I tried compiling your both examples with gcc-5.1.0 (with the -S flag) and they result in exactly the same assembly.

It does not compile under clang-3.7.0 resulting in the following error:

test.cpp:11:23: error: expected '(' for function-style cast or type construction

Pracitcally it means you should not use override in that way.

like image 36
oo_miguel Avatar answered Oct 21 '22 16:10

oo_miguel