Re: Perfect Forwarding + static_assert [C++0x]
On 4 Dez., 07:07, Scott Meyers wrote:
[...]
I really want to forward only a std::string. I came up with this:
template<typename T>
void setName(T&& newName)
{
static_assert(
std::is_same<
std::remove_cv<
std::remove_reference<T>::type
>::type,
std::string
>::value, "T must be a [const] std::string
);
name = std::forward<T>(newName);
};
As Marc said already, a "typename" appears to be missing. In addition,
I'll like to mention that std::decay typically works as a shortcut for
remove_cv<remove_refernence<...>>
VC10 swallows it and seems to behave the way I want.
gcc 4.5 doesn't compile
I guess that's because VC10 doesn't do a proper two-phase lookup.
2. Assuming I want to do what I say I want to do, is there a
better way to do it? I assume I could also play games with
enable_if, but I think the incantation would be no simpler
than the static_assert.
I was just about to suggest enable_if here. That's seems (at least for
function templates) like a good way to constrain them in order to
reduce the size of the overload resolution set. With a failing
enable_if a function doesn't make it into the overload resolution set
while a static_assert would only be checked after overload resolution.
Instead of restricting the parameter to std::string (or references to
string), you should consider conversion, so that you can also pass
string literals:
template<class T>
enable_if< is_convertible<T,string>::value,
void>::type setName(T&& newName)
{
name_ = forward<T>(newName);
}
To hide the template stuff one could use a wrapper that remembers the
address of the argument object and its value category so it can later
perform the corresponding assignment:
template<class T>
class epa // ep = efficient passing / assignment
{
public:
epa(T const& x) : p(&x), q(0) {}
epa(T && x) : p(0), q(&x) {}
void assign_to(T & target) {
if (p) target = *p;
else target = move(*q);
}
private:
T const* p;
T * q;
};
void YourClass:setName(epa<string> newName)
{
newName.assign_to(this->name);
}
Cheers!
Sebastian