Herb Sutter 的 C++Con 2014 演讲中的完美转发器
Perfect forwarder in Herb Sutter's C++Con 2014 talk
在 C++Con 2014 的 Herb Sutter's talk 中,他讨论了按值传递、按引用传递等等。他在这个人为设计的示例中展示的一项技术是:
using namespace std;
class employee{
string name_;
public:
template<class String, class = enable_if_t<!is_same<decay_t<String>, string>::value>>
void set_name(String&& name) noexcept(is_nothrow_assignable<string&, String>::value){
name_ = forward<String>(name);
}
};
我知道 String&&
是一个 通用 或 转发 引用,因为 String
是一个推导的模板类型,因此应该使用 forward<String>(name)
。虽然我在模板元编程方面的经验非常有限,但对我来说,使用 enable_if_t...
的未命名模板参数的目的是什么并不明显,希望能解释一下它的目的。 noexcept
是如何工作的?如果一个人天真地写出什么错误:
template<class String>
void set_name(String&& name){
name_ = forward<String>(name);
}
这个未命名的模板参数是必需的,因为 std::enable_if_t
用法。不需要参数(在模板函数中使用),因此可以不命名。
std::enable_if_t
使用 SFINAE 工作。如果std::enable_if_t
参数为false,则不会为该参数生成函数代码。
参见 some documentation for more information about std::enable_if_t
. You can also look at Template Meta-Programming wikibook or SFINAE and enable_if 文章。
这是为了确保仅使用对 std::string
的左值或右值引用来调用 set_name
,允许任何 cv 限定符。
它使用 SFINAE 工作:如果 decay
ing String
模板参数的结果与 std::string
的类型不同,enable_if_t
将无法通过类型检查,以便从候选集中删除该模板。
在 C++Con 2014 的 Herb Sutter's talk 中,他讨论了按值传递、按引用传递等等。他在这个人为设计的示例中展示的一项技术是:
using namespace std;
class employee{
string name_;
public:
template<class String, class = enable_if_t<!is_same<decay_t<String>, string>::value>>
void set_name(String&& name) noexcept(is_nothrow_assignable<string&, String>::value){
name_ = forward<String>(name);
}
};
我知道 String&&
是一个 通用 或 转发 引用,因为 String
是一个推导的模板类型,因此应该使用 forward<String>(name)
。虽然我在模板元编程方面的经验非常有限,但对我来说,使用 enable_if_t...
的未命名模板参数的目的是什么并不明显,希望能解释一下它的目的。 noexcept
是如何工作的?如果一个人天真地写出什么错误:
template<class String>
void set_name(String&& name){
name_ = forward<String>(name);
}
这个未命名的模板参数是必需的,因为 std::enable_if_t
用法。不需要参数(在模板函数中使用),因此可以不命名。
std::enable_if_t
使用 SFINAE 工作。如果std::enable_if_t
参数为false,则不会为该参数生成函数代码。
参见 some documentation for more information about std::enable_if_t
. You can also look at Template Meta-Programming wikibook or SFINAE and enable_if 文章。
这是为了确保仅使用对 std::string
的左值或右值引用来调用 set_name
,允许任何 cv 限定符。
它使用 SFINAE 工作:如果 decay
ing String
模板参数的结果与 std::string
的类型不同,enable_if_t
将无法通过类型检查,以便从候选集中删除该模板。