完美转发非模板类的方法

时间:2016-04-01 18:47:00

标签: c++ c++11

通常可以在模板类的上下文中看到完美转发。对于非模板类,是否值得制作,例如构造函数是一个模板方法,所以它可以使用完美的转发?如下所示:

class Foo()
{
    public:
        template<typename T>
        Foo(T &&vec) : memberVec(std::forward<T>(vec)) {};

    private:
        std::vector memberVec;
};

优势基本相同,但是当我们知道真正的班级类型时,有什么不同?什么时候这是好的做法,何时不是?

1 个答案:

答案 0 :(得分:5)

非显式单参数ctor是转换ctor。除非Foo应该是可转换的 - 从向量(可能是真的),你应该使它explicit

一般情况下,对于单参数ctors,您需要SFINAE禁用Foo类型才能匹配。当您使用Foo&&(例如,非常量左值)调用Foo const&而不是模板ctor时,隐式FooFoo& ctors是更糟糕的匹配。一个简单的class=std::enable_if_t<!std::is_same<std::decay_t<T>,Foo>>就足够了。

将生成稍多的代码。

在这种情况下,std::vector<X>移动的价格非常便宜,所以

Foo( std::vector<X> vec ):memberVec(std::move(vec)) {}

99%的效率和清晰度。

使用它时,通常会出现完美的转发失败。上面的例子没有它们 - 我可以Foo x({1,2,3})并通过{1,2,3}来构建vec。凭借T&&,它不会被推断,因为它无法推断出T是什么。