Using variational pattern specialization as a template argument

Consider the following:

template <class...>
struct MyT;

template <class T>
struct MyT<T> {};

template <template <class> class TT = MyT> struct A {}; // fine

using B = A<MyT>; // does not compile

int main() {
  return 0;
}

When MyTused as the default argument to A, the compiler (g ++ 5.4.0) is happy. However, when it is used to create an instance A, the story is different:

temp.cpp:19:16: error: type/value mismatch at argument 1 in template parameter list fortemplate<template<class> class TT> struct Ausing B = A<MyT>;
                ^
temp.cpp:19:16: note:   expected a template of type ‘template<class> class TT’, gottemplate<class ...> struct MyT

I can fix this by entering an alias:

template <class T>
using MyTT = MyT<T>;

using B = A<MyTT>; // fine

Question: what is the cause of the error and is there a solution without introducing an alias?

EDIT Note that it is Adeclared as a template template parameter, as shown, and which is not specified for change.

+4
source share
4 answers

, , . , , , , , , .
, :

template <class...>
struct MyT;

template <class T>
struct MyT<T> {};

template <template <class> class TT = MyT> struct A {}; // fine

int main() {
  A<> a;
  return 0;
}

:

,

, .
A :

template <template <class...> class TT = MyT> struct A;

- , , , .

+3

.

-, - . , , , .

, .

.

template<template<class...>class Z> struct foo {};
template<template<class   >class Z> struct bar {};

template<class...>struct a{};
template<class   >struct b{};

foo a b.

bar b.

, , ", ?". ", ", , . ++; , . ( , - , )

, , ++.

, , template<class...>class " , ". .

, template<class>class .

Tl; dr: template<template template<template<class...>class , . , , , std::size_t X std::integral_constant< std::size_t, X >.

+1

" ?", , .

template <class T>
struct MyT {  };

template <template <class> class TT = MyT> struct A 
{};

using B = A<MyT>;

, , .

MyTT, , , , , arg:

template <class T>
using MyTT = MyT<T>;

.

... ? A MyT , A :

template<template<class> class TT = MyT> struct A
{
   // use an instance of TT??
   TT<int> myInstance; // forced to choose `int`
};
0

.

A)

template <class T>
  struct TestStruct {
};

template <
  template <class>
  class TT = TestStruct
>
struct A
{
  int a; // sorry to modify this. This help to show how it works
};

int main() {
  A< TestStruct > b;
  b.a; // it works!
  return 0;
}

This works because the TT template class only accepts a template with <class ...>. A specialized class does not count on this (because it is based on the <class ...> template)

B) even you update the structure A to the template <class ...> one, you still have one more problem. What is a template argument TT? See example below.

template <class...>                                                                                                                 
struct MyT;                                                                                                                         

template <class T>                                                                                                                  
struct MyT<T> {                                                                                                                     
    int a;                                                                                                                          
};                                                                                                                                  

template <                                                                                                                          
    template <class...>                                                                                                             
    class TT = MyT
    // may be you need to add some more typename here, such as
    // typename T1, ... , and then TT<T1> a;                                                                                                                 
>                                                                                                                                   
struct A                                                                                                                            
{                                                                                                                                   
    TT<int> a; 
    // Here ! TT is a template only, do not have the template parameters!!!                                                                                                                   
};                                                                                                                                  

int main() {                                                                                                                        

  A< MyT > b;                                                                                                                                        
  b.a;     // it works!!                                                                                                                         

  return 0;                                                                                                                         
}                                                                                                                                   

But if you really cannot update the signature of these definitions, you can make a proxy class

template< class T >
struct Proxy : MyT<T>
{
};
0
source

Source: https://habr.com/ru/post/1655841/


All Articles