Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inequivalence of templated types using aliased template names [duplicate]

We have observed a strange behaviour in the compilation of the follwing source code:

template<template<class> class TT> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>;  int main() {   X<Y> y;   X<Z> z;   z = y; // it fails here } 

This is a slightly modified example taken from the c++11 standard proposal for template aliases: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf (See page 4) Also note that the proposal "declares y and z to be of the same type." In our interpretation it should therefore be possible to assign (or copy construct) z from y.

However, this code doesn't compile with gcc 4.8.1 nor with clang 3.3. Is this an error in the compiler or did we misunderstand the standard?

Thanks in advance, craffael et al ;)

P.S. The Clang error message is:

error: no viable overloaded '='  note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'X<template Y>' to 'const X<template Z>' for 1st argument template<template<class> class TT> struct X { };  note: candidate function (the implicit move assignment operator) not viable: no known conversion from 'X<template Y>' to 'X<template Z>' for 1st argument template<template<class> class TT> struct X { }; 
like image 639
craffael Avatar asked Oct 11 '13 09:10

craffael


People also ask

What are template arguments enlist types of template arguments?

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.)

How many types of templates are there in C++?

There are three kinds of templates: function templates, class templates and, since C++14, variable templates. Since C++11, templates may be either variadic or non-variadic; in earlier versions of C++ they are always non-variadic.

Why do we use :: template template parameter?

8. Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

Which is correct example of template parameters?

For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.


2 Answers

The current standard doesn't say so, but the intention is that y and z have the same type. There is an open Core Working Group issue for this: http://wg21.cmeerw.net/cwg/issue1286

like image 158
cmeerw Avatar answered Sep 18 '22 18:09

cmeerw


I think you are confusing a type and a template (or a template alias). You have Y, which is one template and Z, which is another one. If you think that Y == Z, you are wrong. Only if you turn them into types, those types are the same, e.g. Y<int> is the same type as Z<int>. In your example:

template<class T> struct X { };  template<class> struct Y { }; template<class T> using Z = Y<T>;  int main() {   X<Y<int>> y;   X<Z<int>> z;   z = y; // works } 

In your original code you referred to them with X<Y> and X<Z>, but as Y is not the same as Z, so are X<Y> and X<Z> different types.

like image 40
Daniel Frey Avatar answered Sep 21 '22 18:09

Daniel Frey