Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;将参数包传递给类_C++_C++11_C++14 - Fatal编程技术网

C++ C++;将参数包传递给类

C++ C++;将参数包传递给类,c++,c++11,c++14,C++,C++11,C++14,我希望有一个类,它可以获取相同类型的无限参数,并将它们存储到一个向量中。应该是这样的: class A(int a, int b, **N time parameter of type T**) : data(**vector will get N times type T**) { } protected: vector<T> data; A类(int A,int b,**N类型T**的时间参数) :data(**向量将得到N次类型T**) { } 受保护的: 矢量数据; 我

我希望有一个类,它可以获取相同类型的无限参数,并将它们存储到一个向量中。应该是这样的:

class A(int a, int b, **N time parameter of type T**)
: data(**vector will get N times type T**)
{
}

protected:
vector<T> data;
A类(int A,int b,**N类型T**的时间参数)
:data(**向量将得到N次类型T**)
{
}
受保护的:
矢量数据;
我应该如何实施它?解决方案可以是c++11/14 我遇到了一些错误,例如“参数包没有用“…”展开”,等等。

给你:

#include <iostream>
#include <vector>

template<class T>
struct V
{
    V(int n, std::initializer_list<T> l)
        : data(l)
    {
        (void) n;
    }

    std::vector<T> data;
};

int main()
{
    V<int> v(0,{1,2,3});
}
#包括
#包括
模板
结构V
{
V(int n,std::初始值设定项列表l)
:数据(l)
{
(无效)n;
}
std::矢量数据;
};
int main()
{
V(0,{1,2,3});
}

这不是一个完美的示例,因为需要使用奇怪的语法
(n,{optional,arguments,of,same,type})
构造一个对象,但它确实提供了所需的行为。

此代码示例可能有用:

#include <vector>
#include <utility>

template<typename T>
class MyClass {
public:
    template<typename ...Args>
    MyClass(int a, int b, Args&& ...args) :data{ std::forward<Args>(args)... } {}
private:
    std::vector<T> data;
};

int main() {
    MyClass<char> sample(1, 2, 'a', 'b');
    return 0;
}
#包括
#包括
模板
类MyClass{
公众:
模板
MyClass(intA、intB、Args&…Args):数据{std::forward(Args)…}{
私人:
std::矢量数据;
};
int main(){
MyClass样本(1,2,'a','b');
返回0;
}

[编辑]:添加了std::forward,添加了missing include for utility

以下示例与fr3nzy90类似,但在即将推出的C++17中,它将允许从构造函数参数自动推断
T

template <class T>
class MyContainer {
    private:
    std::vector<T> data;

    public:
    // Take the first T value explicitly so it can be used to deduce
    // T from the constructor arguments (C++17 feature).
    template <class... Ts>
    MyContainer(int a, int b, T const & tval, Ts const &... tvals) :
      data{tval, tvals...} {
        …
    }

    // Special case, empty list, no implicit type deduction, because
    // there is no T value to deduce it from.
    MyContainer(int a, int b) {
        …
    }
};
模板
类霉菌容器{
私人:
std::矢量数据;
公众:
//显式获取第一个T值,以便用于推断
//T来自构造函数参数(C++17特性)。
模板
MyContainer(内部a、内部b、T常量和tval、Ts常量和…tval):
数据{tval,tval…}{
…
}
//特殊情况,空列表,无隐式类型推断,因为
//没有T值可供推断。
MyContainer(内部a、内部b){
…
}
};

假设T可以是任何东西,甚至是相当大或不可复制的东西,我们希望:

  • 通过完美的转发保持效率

  • 检查类型

  • std::initializer\u list
    满足2,但不满足1

    简单的变量模板展开满足1而不是2

    此解决方案使用可变模板扩展和
    enable_if
    强制执行类型兼容性

    #include <vector>
    #include <utility>
    #include <string>
    
    
    namespace detail
    {
        constexpr bool all()
        {
            return true;
        }
    
        template<class...Rest>
        constexpr bool all(bool b, Rest...rest)
        {
            return b and all(rest...);
        };
    
    }
    
    
    template<class T>
    class A
    {
    public:
        using value_type = T;  // say
    
        template<class...Rest,
                std::enable_if_t<detail::all(std::is_convertible<Rest, value_type>::value...)>* = nullptr>
        A(int a, int b, Rest&&...rest)
                : a_(a), b_(b)
        {
            this->fill(std::forward_as_tuple(std::forward<Rest>(rest)...),
                       std::make_index_sequence<sizeof...(Rest)>());
        }
    
    private:
        template<class Tuple, std::size_t...Is>
        void fill(Tuple&& t, std::index_sequence<Is...> seq)
        {
            data_.reserve(seq.size());
            using expand = int[];
            void(expand{ 0,
                         (data_.push_back(std::move(std::get<Is>(t))), 0)...
            });
        }
    private:
        int a_, b_;
        std::vector<value_type> data_;
    };
    
    
    int main()
    {
        using namespace std::literals;
    
        auto a = A<double>(1, 2, 4.3, 5.5, 6.6);
    
        auto b = A<std::string>(1, 2, "the", "cat"s, "sat on the mat");
    
        // error: no matching constructor...
    //    auto err = A<std::string>(1, 2, "the", "cat"s, 0.1);
    
    }
    
    #包括
    #包括
    #包括
    名称空间详细信息
    {
    constexpr bool all()
    {
    返回true;
    }
    模板
    constexpr bool all(bool b,Rest…Rest)
    {
    返回b和所有(剩余…);
    };
    }
    模板
    甲级
    {
    公众:
    使用value_type=T;//例如
    模板
    A(整数A、整数b、余数和余数)
    :a_(a),b_(b)
    {
    这个->填充(std::forward)作为(std::forward(rest),
    std::make_index_sequence());
    }
    私人:
    模板
    空白填充(元组和t,标准::索引顺序)
    {
    数据保留(seq.size());
    使用expand=int[];
    void(展开{0,
    (数据向后推(std::move(std::get(t))),0)。。。
    });
    }
    私人:
    int a_uu,b_uu;
    std::矢量数据;
    };
    int main()
    {
    使用名称空间std::literals;
    自动a=a(1,2,4.3,5.5,6.6);
    自动b=A(1,2,“猫”坐在垫子上);
    //错误:没有匹配的构造函数。。。
    //自动错误=A(1,2,“该”、“类别”s,0.1);
    }
    
    您希望如何传递参数?事实上,使用
    std::vector
    可以编写类似
    aa(1,2,{'A','b','c')的代码
    。T是一种像double这样的内在类型,还是一个需要移动的对象?您可能需要
    std::forward
    …args
    扩展到
    数据
    ;除此之外,我更喜欢你的解决方案,谢谢!这正是我想要的