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 T
s but not other T
s.
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
C++ Vector Size. Why -1 Is Greater Than Zero
What Belongs in an Educational Tool to Demonstrate the Unwarranted Assumptions People Make in C/C++
Behavior of Post Increment in Cout
Arrays VS Vectors: Introductory Similarities and Differences
Is the 'Override' Keyword Just a Check For a Overridden Virtual Method
Can Any One Provide Me a Sample of Singleton in C++
How to Concatenate Multiple C++ Strings on One Line
Const Int' Vs. 'Int Const' as Function Parameters in C++ and C
Pointers, Smart Pointers or Shared Pointers
What Does "Default" Mean After a Class' Function Declaration
What Are the Advantages of Using Nullptr
How to Read a Value from the Windows Registry
What Exactly Do "Ib" and "Ub" Mean
C++ - Why Is Boost::Hash_Combine the Best Way to Combine Hash-Values
Difference Between Erase and Remove
Can the Template Parameters of a Constructor Be Explicitly Specified