Why Function Template Cannot Be Partially Specialized

Why function template cannot be partially specialized?

AFAIK that's changed in C++0x.

I guess it was just an oversight (considering that you can always get the partial specialization effect with more verbose code, by placing the function as a static member of a class).

You might look up the relevant DR (Defect Report), if there is one.

EDIT: checking this, I find that others have also believed that, but no-one is able to find any such support in the draft standard. This SO thread seems to indicate that partial specialization of function templates is not supported in C++0x.

EDIT 2: just an example of what I meant by "placing the function as a static member of a class":

#include <iostream>
using namespace std;

// template<typename T, typename U> void f() {} //allowed!
// template<> void f<int, char>() {} //allowed!
// template<typename T> void f<char, T>() {} //not allowed!
// template<typename T> void f<T, int>() {} //not allowed!

void say( char const s[] ) { std::cout << s << std::endl; }

namespace detail {
template< class T, class U >
struct F {
static void impl() { say( "1. primary template" ); }
};

template<>
struct F<int, char> {
static void impl() { say( "2. <int, char> explicit specialization" ); }
};

template< class T >
struct F< char, T > {
static void impl() { say( "3. <char, T> partial specialization" ); }
};

template< class T >
struct F< T, int > {
static void impl() { say( "4. <T, int> partial specialization" ); }
};
} // namespace detail

template< class T, class U >
void f() { detail::F<T, U>::impl(); }

int main() {
f<char const*, double>(); // 1
f<int, char>(); // 2
f<char, double>(); // 3
f<double, int>(); // 4
}

Why does the C++ standard not allow function template partial specialization?

From http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#229 linked by @danh in the comments above:

Notes from 10/00 meeting:

A major concern over the idea of partial specialization of function templates is that function templates can be overloaded, unlike class templates. Simply naming the function template in the specialization, as is done for class specialization, is not adequate to identify the template being specialized.

C++ function template partial specialization?

Function partial specialization is not yet allowed as per the standard. In the example, you are actually overloading & not specializing the max<T1,T2> function.

Its syntax should have looked somewhat like below, had it been allowed:

// Partial specialization is not allowed by the spec, though!
template <typename T>
inline T const& max<T,T> (T const& a, T const& b)
{ ^^^^^ <--- [supposed] specializing here
return 10;
}

In the case of a function templates, only full specialization is allowed by the C++ standard, -- excluding the compiler extensions!

Why can't we specialize concepts?

Because it would ruin constraint normalization and subsumption rules.

As it stands now, every concept has exactly and only one definition. As such, the relationships between concepts are known and fixed. Consider the following:

template<typename T>
concept A = atomic_constraint_a<T>;

template<typename T>
concept B = atomic_constraint_a<T> && atomic_constraint_b<T>;

By C++20's current rules, B subsumes A. This is because, after constraint normalization, B includes all of the atomic constraints of A.

If we allow specialization of concepts, then the relationship between B and A now depends on the arguments supplied to those concepts. B<T> might subsume A<T> for some Ts but not other Ts.

But that's not how we use concepts. If I'm trying to write a template that is "more constrained" than another template, the only way to do that is to use a known, well-defined set of concepts. And those definitions cannot depend on the parameters to those concepts.

The compiler ought to be able to compute whether one constrained template is more constrained than another without having any template arguments at all. This is important, as having one template be "more constrained" than another is a key feature of using concepts and constraints.

Ironically, allowing specialization for concepts would break (constrained) specialization for other templates. Or at the very least, it'd make it really hard to implement.



Related Topics



Leave a reply



Submit