S
Scott Meyers
Function templates can be partially or fully specialized, but is it
possible to specialize templates that perform perfect forwarding? My
sense is that it's not, because the special type deduction rule that
makes perfect forwarding work (the one that distinguishes lvalue and
rvalue arguments for function templates with a declared parameter type
of T&& -- 14.8.2.1/3 in the most recent draft C++0x) seems to apply only
to general templates. But maybe I'm overlooking something.
If I give the program below to VC10 and gcc 4.5, they behave as the
comments indicate. My attempt to partially specialize a perfect
forwarding template for pointer types fails. The code compiles and
runs, but the partial specialization is invoked only for rvalue pointer
types, never for lvalue pointer types.
I have two questions:
1. Am I correct that perfect forwarding templates cannot be specialized?
2. Does it ever make sense to want to?
Thanks,
Scott
#include <iostream>
#include <utility>
void f(std::string*&)
{
std::cout << "f(lref)\n";
}
void f(const std::string*&)
{
std::cout << "f(const lref)\n";
}
void f(std::string*&&)
{
std::cout << "f(rref)\n";
}
template<typename T>
void fwd(T&& param)
{
std::cout << "General forwarding template => ";
f(std::forward<T>(param));
}
template<typename T>
void fwd(T*&& param)
{
std::cout << "T*&& forwarding template => ";
f(std::forward<T*>(param));
}
int main()
{
std::string* ps;
const std::string *pcs;
fwd(ps); // calls general template
fwd(pcs); // calls general template
fwd((std::string*&&)ps); // calls specialized template
}
possible to specialize templates that perform perfect forwarding? My
sense is that it's not, because the special type deduction rule that
makes perfect forwarding work (the one that distinguishes lvalue and
rvalue arguments for function templates with a declared parameter type
of T&& -- 14.8.2.1/3 in the most recent draft C++0x) seems to apply only
to general templates. But maybe I'm overlooking something.
If I give the program below to VC10 and gcc 4.5, they behave as the
comments indicate. My attempt to partially specialize a perfect
forwarding template for pointer types fails. The code compiles and
runs, but the partial specialization is invoked only for rvalue pointer
types, never for lvalue pointer types.
I have two questions:
1. Am I correct that perfect forwarding templates cannot be specialized?
2. Does it ever make sense to want to?
Thanks,
Scott
#include <iostream>
#include <utility>
void f(std::string*&)
{
std::cout << "f(lref)\n";
}
void f(const std::string*&)
{
std::cout << "f(const lref)\n";
}
void f(std::string*&&)
{
std::cout << "f(rref)\n";
}
template<typename T>
void fwd(T&& param)
{
std::cout << "General forwarding template => ";
f(std::forward<T>(param));
}
template<typename T>
void fwd(T*&& param)
{
std::cout << "T*&& forwarding template => ";
f(std::forward<T*>(param));
}
int main()
{
std::string* ps;
const std::string *pcs;
fwd(ps); // calls general template
fwd(pcs); // calls general template
fwd((std::string*&&)ps); // calls specialized template
}