Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
243 views
in Technique[技术] by (71.8m points)

c++ - Why is this nested variadic template an invalid argument?

If I define a struct template Bar which accepts a template argument:

template <template <int,bool,char> class>
struct Bar {};

I can instantiate it using a struct template such as Zod:

template <int,bool,char> struct Zod {};
Bar<Zod> a;

I can also instantiate it using a nested struct template such as JKL:

struct GHI {
  template <int,bool,char>
  struct JKL {};
};
Bar <GHI::JKL> b;

Why can't I instantiate Bar using a nested variadic struct template such as DEF?:

template <typename ...Ts>
struct ABC {
  template <Ts ...>
  struct DEF {};
};

Bar<ABC<int,bool,char>::DEF> c;

G++ 4.9.2 complains of a type/value mismatch; while Clang 3.4.2's error reports that the template template argument has different template parameters than its corresponding template template parameter.

question from:https://stackoverflow.com/questions/30292955/why-is-this-nested-variadic-template-an-invalid-argument

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Let's give DEF's parameter pack a name for ease of reference:

template <typename ...Ts>
struct ABC {
  template <Ts ... Values>
  struct DEF {};
};

The key point here is that by [temp.param]/p15, Ts... Values is both a pack expansion of Ts and a declaration of a parameter pack Values.

If a template-parameter is [...] a parameter-declaration that declares a parameter pack (8.3.5), then the template-parameter is a template parameter pack (14.5.3). A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded parameter packs is a pack expansion.

Since DEF takes a non-type parameter pack, it doesn't match a template template parameter that doesn't take packs ([temp.arg.template]/p3):

A template-argument matches a template template-parameter P when each of the template parameters in the template-parameter-list of the template-argument’s corresponding class template or alias template A matches the corresponding template parameter in the template-parameter-list of P. Two template parameters match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are equivalent (14.5.6.1), and for template template-parameters, each of their corresponding template-parameters matches, recursively. When P’s template-parameter-list contains a template parameter pack (14.5.3), the template parameter pack will match zero or more template parameters or template parameter packs in the template-parameter-list of A with the same type and form as the template parameter pack in P (ignoring whether those template parameters are template parameter packs).

To be sure, Values is rather weird for packs - for every specialization of ABC, Values must contain a fixed number of arguments - but under the current rules it's still a pack, so the rules for packs apply.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...