2

I work with template template parameters and want to construct new types based on template template parameters defined at another location. This sometimes works, but I think I miss something fundamentally, conceptually.

In the below minimal (I hope not too much distorted) example I expect the types of Example<GerericTemplate> and MakeAnotherX<Example<GenericTemplate>>::type to be identical, but they aren't always.

struct Something {};

template <template <typename> typename TemplateParameter>
struct Example {

  template <typename T>
  using InputTemplate = TemplateParameter<T>; 

  using FullType = TemplateParameter<Something>;

 private:
  FullType fData;
};

template <typename T>
struct GenericTemplate {};

// this works with (recent) GCC, but the static_assert below fails with clang
template <typename ExistingType, 
          template <typename> typename _InputTemplate 
                                = ExistingType::template InputTemplate> 
struct MakeAnother1 {
  using type = Example<_InputTemplate>;
};

// this compiles, but static_assert below fails for both (recent) gcc and clang
template <typename ExistingType> 
struct MakeAnother2 {
  template <typename T> using _InputTemplate 
                     = typename ExistingTemplate::template InputTemplate<T>;
  using type = Example<_InputTemplate>;
};


#include <type_traits>
int main() {
  using type1 = Example<GenericTemplate>;
  static_assert(std::is_same<type1, MakeAnother1<type1>::type >::value, "this is not the same");
  static_assert(std::is_same<type1, MakeAnother2<type1>::type >::value, "this is not the same");

 return 0;
}

this example in godbolt

So far I am using gcc and clang (-std=c++17) for testing (and production), but in general I just wish to have standard compliant code. I really would like to be able to to reuse template template parameters in different context and classes as described in the minimal example above.

What is the correct way to achieve this in a robust manner? Also: is the fact that MakeAnother1 works with GCC a feature or a bug of GCC (and vice versa for clang)?

The "real code" is significantly more complex, so in particular I want those "Make" helper structs to work on new types.

Update

An earlier conceptually identical version of this question was asked about 6 years ago see old post. The news is that today this work on gcc version 5 and beyond but still no other compiler seems to support it. Unfortunately the discussion on CWG seems to have stalled on this point and could benefit from a reminder?

At this stage: after this update, if you prefer we can of course close this report here now. Thanks for all help!

Ralf Ulrich
  • 1,575
  • 9
  • 25
  • 1
    Please use descriptive names. Using `T` for a template type is ok when you are doing something simple; once you have multiple types of different kinds and multiple template floating around, it is pointlessly confusing. – Yakk - Adam Nevraumont Feb 24 '19 at 04:36
  • I am happy to change that, but to clarify, you want me to use longer and unique class and template parameter names? – Ralf Ulrich Feb 24 '19 at 05:06
  • Meaningful names. Not `a` `b` `c` `AT` whatever. Say what the thing means. Naming is hard, but unnamed stuff is painful to read. – Yakk - Adam Nevraumont Feb 24 '19 at 05:12
  • ok. Let's see if this is better... – Ralf Ulrich Feb 24 '19 at 05:39
  • 1
    This is [Core Language Issue 1286](https://stackoverflow.com/questions/19314277/c11-template-alias-as-template-template-argument-leads-to-different-type) – xskxzr Feb 24 '19 at 06:43
  • That is most interesting to read. Unfortunately it seem that this is a very orphan issue, last comment is ~3years old. So very unfortunately I probably cannot rely on it, or I have to restrict to GCC only. You experts: are not more people like me who think this is an important feature and we can reinforce its usefulness? – Ralf Ulrich Feb 24 '19 at 08:41
  • Per xskxzr: possible duplicate of [C++11 template alias as template template argument leads to different type?](https://stackoverflow.com/questions/19314277/c11-template-alias-as-template-template-argument-leads-to-different-type) – Davis Herring Feb 24 '19 at 09:32

0 Answers0