c++ - Why can't new template parameters be introduced in full specializations? -
in where in c++11 standard prohibit 'template <typename t> class {...}; template <typename t> class a<int> {...};' (if anywhere)?, it's been confirmed following syntax disallowed in c++11 standard:
/* invalid c++ */ template <typename t> class { public: t t; }; // phony "full specialization" mistakenly attempts // introduce *new* template parameter template <typename t> class a<int> { public: int i; t t; };
with full understanding above syntax not represent valid c++, nonetheless imagine syntactically unambiguous use of above code snippet, follows:
a<float> a1; a<int><double> a2; a1.t = 2.0f; a2.i = 2; a2.t = 2.0;
it seem syntactically , semantically unambiguous c++ support syntax above.
(if intended semantics not clear anybody, please post comment , explain.)
i describe syntax "introducing new template parameter in full specialization".
in imagined scenario of c++ compiler modified support above syntax , semantics, compiler see a<int> a2;
, recognize attempted instantiation matches primary template; search specializations , find , select full specialization a<int>
(ignoring <double>
); note full specialization introduces new template parameter t
in case of declared variable a2
double
.
if i'm right above syntax , semantics unambiguous, i'd know why not part of c++. can think of 3 reasons, perhaps answer different or more complicated.
- there (almost) no real-world scenarios useful
- it's complex current compilers asked support
- there many potential conflicts other language features necessitate many new rules
- actually, fourth possibility - above syntax , semantics useful in real-world scenarios , could reasonably included in standard, it's not part of current standard.
i'd know why isn't supported in c++ - correct 1 of bullet points provides answer?
oooh, explodes in funny ways.
for clarity, assume mean example code,
a<double> a; // okay a<int> a2; // not okay, a<int> not class class template.
now let's try use in other templates. consider
template<typename t> void function<a<t> const &a) { ... } a<double> a; a<int><double> a2; function(a); // looks okay. function(a2); // er...compiler error, guess?
that's not bad yet; compiler complain that. think we're beginning see how bit strange, though. well, take notch:
template<template<typename> class a> struct foo { ... }; foo<a> f; // work, now?
if answer no, if specialisation not known @ point of compilation?
edit: expanding bit, consider real-world scenario template-template arguments call pack traits:
template<template<typename> class, typename...> struct applies_to_all; template<template<typename> class predicate, typename t, typename... pack> struct applies_to_all<predicate, t, pack...> { static bool const value = predicate<t>::value && applies_to_all<predicate, pack...>::value; }; template<template<typename> class predicate> struct applies_to_all<predicate> { static bool const value = true; }; ... bool b = applies_to_all<std::is_integral, int, long, double>::value;
and feed a
that's class int
, class template int
. try work out
applies_to_all<a, double, float, std::string, int>::value
and note simple case not code you're see. stuff nested 3 levels deep in other templates, looks this:
applies_to_all<a, t...>::value
possibly behavior defined mathematically consistent, doubt 1 defined useful. it's not pola-compliant.
there's lot more come along these lines. blurring lines between classes , class templates in fashion bound break sorts of stuff.
Comments
Post a Comment