S
Scott Meyers
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)
{
);
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
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)
{
std::stringstatic_assert(std::is_same said:>::type,
"T must be a [const] std::string“>::value,
);
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