18277

When specializing a class, how can I take a different number of template parameters?

Question:

I just asked this question: <a href="https://stackoverflow.com/q/52317134/2642059" rel="nofollow">Can I get the Owning Object of a Member Function Template Parameter?</a> and <a href="https://stackoverflow.com/users/1774667/yakk-adam-nevraumont" rel="nofollow">Yakk - Adam Nevraumont</a>'s answer had the code:

template<class T> struct get_memfun_class; template<class R, class T, class...Args> struct get_memfun_class<R(T::*)(Args...)> { using type=T; };

These is clearly an initial declaration and then a specialization of struct get_memfun_class. But I find myself uncertain: <strong>Can specializations have a different number of template parameters?</strong>

For example, is something like this legal?

template<typename T> void foo(const T&); template<typename K, typename V> void foo<pair<K, V>>(const pair<K, V>&);

Are there no requirements that specializations must take the same number of parameters?

Answer1:

You seem to confuse the template parameters of the explicit specialization and the template arguments you use to specialize the template.

template<class T> // one argument struct get_memfun_class; // get_memfun_class takes one template (type) argument template<class R, class T, class...Args> struct get_memfun_class<R(T::*)(Args...)> { // ^^^^^^^^^^^^^^^^ // one type argument using type=T; }; // explicit specialization takes one template argument

Yes, there are three template parameters for the explicit specialization, but that doesn't mean that the explicit specialization takes three arguments. They are there to be deduced. You can form a single type using multiple type parameters, which is what is happening there. Also consider that you can fully specialize a template:

template <> struct get_memfun_class<void>; // ^^^^ // one type argument

Here it's the same thing. Yes, the explicit specialization takes no parameters, but that just means that there is none to be deduced and indeed you are explicitly writing a template parameter (void) and so the amount of template arguments of the specialization match those of the primary template.

Your example is invalid because you cannot partially specialize functions.

Answer2:

<blockquote>

Are there no requirements that specializations must take the same number of parameters?

</blockquote>

There is; and is satisfied in your example.

When you write

template<class T> struct get_memfun_class;

you say that get_mumfun_class is a template struct with a single template typename argument; and when you write

template<class R, class T, class...Args> struct get_memfun_class<R(T::*)(Args...)> { using type=T; };

you define a specialization that receive a single template typename argument in the form R(T::*)(Args...).

From the single type R(T::*)(Args...), you can deduce more that one template paramenters (R, T and the variadic Args..., in this example) but the type R(T::*)(Args...) (a method of a class that receive a variadic list of arguments) remain one.

<blockquote>

For example, is something like this legal?

</blockquote> template<typename T> void foo(const T&); template<typename K, typename V> void foo<pair<K, V>>(const pair<K, V>&);

No, but (as written in comments) the second one isn't a class/struct partial specialization (where std::pair<K, V> remain a single type), that is legal; it's a template <strong>function</strong> partial specialization that is forbidden.

But you can <strong>full</strong> specialize a template function; so it's legal (by example)

template<> void foo<std::pair<long, std::string>(const std::pair<long, std::string>&);

as is legal the full specialization for get_memfun_class (to make another example)

template<> struct get_memfun_class<std::pair<long, std::string>> { using type=long long; };

Recommend

  • Converting string to unsigned int returns the wrong result
  • In this example why do I need CRTP?
  • Is there any way I can prevent a namespace from adding further classes in C++?
  • How to make this very long url appear short?
  • best backbone.js and require.js boilerplate for huge apps [closed]
  • Legal legacy code using pointers suddenly becomes UB
  • “class template has already been declared as a non-class template”
  • Prolog - remove the non unique elements
  • Apple Watch page based interface overflowing on initial controller
  • DirectX game with no prerequisite software to run
  • Mapping C# classes to Lua functions via dll
  • Collect and run all junit tests in parallel with each test class in its own JVM (parallelization by
  • IP and domain create different session
  • C Language: Why does malloc() return a pointer, and not the value?
  • Fast way to alphabetically sort the contents of a file in java
  • What distributed message queues support millions of queues?
  • Member function pointer cast, from Derived to Base class
  • How can I have equal heights for inner elements of flexbox grid/boxes/cards without using jQuery?
  • jQuery Mobile - Dialogs without changing hash
  • Embedding a Google map
  • What version of Java should I use with Cassandra 2.0?
  • The symbol you provided is not a function
  • Partial specialization of a class template in derived class affects base class
  • What is the likely cause of a net::ERR_CONNECTION_ABORTED when uploading a file to Spring
  • SqlCommand back up Database
  • What Makes These Two Array Adds Different?
  • VBA Excel, loop through variables
  • blade.php method outputting it's result to the form
  • NUnit 3.0 TestCase const custom object arguments
  • xcode don't localize specific strings
  • C++ Partial template specialization - design simplification
  • Is there a javascript serializer for JSON.Net?
  • NetLogo BehaviorSpace - Measure runs using reporters
  • Spring security and special characters
  • Where to put my custom functions in Wordpress?
  • JSON with duplicate key names losing information when parsed
  • Buffer size for converting unsigned long to string
  • C# - Getting references of reference
  • Binding checkboxes to object values in AngularJs
  • How to Embed XSL into XML