对于构造函数,如何在variadic-templates和std :: initializer_list之间进行选择? [英] For constructors, how do I choose between variadic-templates vs std::initializer_list?

查看:141
本文介绍了对于构造函数,如何在variadic-templates和std :: initializer_list之间进行选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在c ++ 11的当前状态(比如说gcc 4.7.2)中,我应该如何选择使用 variadic-template std :: initializer_list 当我需要一个可以接受变量参数的构造函数时

In the current state of c++11 (say gcc 4.7.2), how should I choose between using a variadic-template or a std::initializer_list when I need a constructor that can take variable arguments?

推荐答案

不同类型,而 std :: initializer_list 是以参数的类型为模板。这意味着列表中所有元素的类型必须相同(或可转换为基础类型,但不允许缩小转换)。

A variadic template allows you providing arguments of different types, while an std::initializer_list is templated with the type of the argument. This means the type of all the elements in the list must be the same (or convertible to the underlying type, but no narrowing conversions are allowed). Depending on whether or not this is desirable for you, you may choose one or the other.

此外,如果您需要使用可变参数模板,通常是默认选项。完美转发,因为句法形式 T&& 可以绑定到左值引用和右值引用,而类似的类型推导不能对 initializer_list

Also, a variadic template is usually the default choice if you need perfect forwarding, in that the syntactic form T&& can bind to both lvalue references and rvalue references, while a similar type deduction cannot be performed for initializer_list:

struct A
{
    // Deduces T& for lvalue references, T for rvalue references, and binds to both
    template<typename... Ts>
    A(Ts&&...) { }

    // This is an rvalue reference to an initializer_list. The above type deduction
    // does not apply here
    template<typename T>
    A(initializer_list<T>&&) { }
};

另请注意,构造函数接受 initializer_list 将在默认情况下使用统一初始化语法(即花括号)时调用,即使另一个可行的构造函数存在。这可能是也可能不是你想要的:

Also notice, that a constructor accepting an initializer_list will be invoked by default when you use uniform initialization syntax (i.e. curly braces), even though another viable constructor exists. This may or may not be something you wish to have:

struct A
{
    A(int i) { }
};

struct B
{
    B(int) { }
    B(std::initializer_list<A>) { }
};

int main()
{
    B b {1}; // Will invoke the constructor accepting initializer_list
}

这篇关于对于构造函数,如何在variadic-templates和std :: initializer_list之间进行选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆