Suppose I have a setter function, and I'd like it to forward its argument as an
lvalue or an rvalue to whatever constructor will be used to do the setting. I
can overload the setter like this:
class Widget {
public:
...
void setName(const std::string& newName) // set from lvalue
{ name = newName; }
void setName(std::string&& newName) // set from rvalue
{ name = std::move(newName); }
...
private:
std::string name;
};
I can also use a template member function and perfect forwarding:
class Widget {
public:
...
template<typename T>
void setName(T&& newName)
{ name = std::forward<T>(newName); }
...
};
The template will forward any type that can be used to initialize the string,
i.e., it will accept types other than std::string. Suppose, for whatever wacky
reason, 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::rem ove_reference<T>::type
>::type,
std::string
>::value,
"T must be a [const] std::string“
);
name = std::forward<T>(newName);
};
VC10 swallows it and seems to behave the way I want. gcc 4.5 doesn't compile
it. Questions:
1. Is there some reason the above should not compile?
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.
Thanks,
Scott
--
* C++ and Beyond Encore!: Meyers, Sutter, & Alexandrescu, Dec. 13-16 near
Seattle (
http://cppandbeyond.com/)
* License my training materials for commercial (
http://tinyurl.com/yfzvkp9) or
personal use (
http://tinyurl.com/yl5ka5p).