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 工作:如果 decaying String 模板参数的结果与 std::string 的类型不同,enable_if_t 将无法通过类型检查,以便从候选集中删除该模板。