Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_C++11_Polymorphism_Variadic Templates - Fatal编程技术网

C++ 无虚拟或遗传的多态载体

C++ 无虚拟或遗传的多态载体,c++,templates,c++11,polymorphism,variadic-templates,C++,Templates,C++11,Polymorphism,Variadic Templates,我正在尝试实现一个向量,它可以包含几种类型的元素,并且可以对所有类型的元素应用一个函数。使用基类、虚拟函数和继承很容易做到这一点,但我不想使用它。以下是我到目前为止的成就: #include <iostream> #include <vector> #include <tuple> // this will be my new polymorphic vector; template<typename... Ts> class myvector

我正在尝试实现一个向量,它可以包含几种类型的元素,并且可以对所有类型的元素应用一个函数。使用基类、虚拟函数和继承很容易做到这一点,但我不想使用它。以下是我到目前为止的成就:

#include <iostream>
#include <vector>
#include <tuple>

// this will be my new polymorphic vector;
template<typename... Ts>
class myvector {
    std::tuple<std::vector<Ts>...> vectors;

    template <template<typename> class funtype>
    void for_each() {
    }

    template <template<typename> class funtype, typename X, typename... Xs>
    void for_each() {
        std::vector<X>& vector = std::get<std::vector<X>>(vectors);
        for ( X& x : vector ) {
            funtype<X> fun;
            fun(x);
        }
        for_each<funtype, Xs...>();
    }

public:
    template <typename T>
    void push_back(const T& t) {
        std::vector<T>& vector = std::get<std::vector<T>>(vectors);
        vector.push_back(t);
    }

    template <typename T>
    void pop_back() {
        std::vector<T>& vector = std::get<std::vector<T>>(vectors);
        vector.pop_back();
    }

    /* here I would like to pass a function, or function object that 
     * can be expanded to all underlying types. I would prefer to just 
     * give a function name, that has an implementation to all types in Ts
     */
    template <template<typename> class funtype>
    void ForEach() {
        for_each<funtype,Ts...>();
    }
};


struct foo {
};

struct bar {
};

template <typename T>
void method(T& t);

template<>
void method(foo& b) {
    std::cout << "foo" << std::endl;
}

template<>
void method(bar& b) {
    std::cout << "bar" << std::endl;
}

int main()
{
    myvector<foo,bar> mv;
    mv.push_back( foo{} );
    mv.push_back( bar{} );
    mv.ForEach<method>();
}
#包括
#包括
#包括
//这将是我的新多态载体;
模板
类myvector{
std::元组向量;
模板
对每个()无效{
}
模板
对每个()无效{
std::vector&vector=std::get(vectors);
对于(X&X:vector){
趣味趣味;
乐趣(x);
}
每个人都有一张照片;
}
公众:
模板
无效推回(施工T&T){
std::vector&vector=std::get(vectors);
向量。推回(t);
}
模板
void pop_back(){
std::vector&vector=std::get(vectors);
vector.pop_back();
}
/*这里我想传递一个函数,或者函数对象
*可以扩展到所有底层类型。我更喜欢
*给出一个函数名,该函数名对Ts中的所有类型都有实现
*/
模板
void ForEach(){
每个人都有一张照片;
}
};
结构foo{
};
结构条{
};
模板
空隙法(T&T);
模板
无效方法(foo&b){

std::cout一种常见的解决方案是将函数对象与一组
操作符()一起使用。


如果我们想添加对此类函数对象的支持,我们可以定义
ForEach
,如下所示:

template <typename Elem, typename Fun>
void for_each(Fun&& fun) {
    std::vector<Elem>& vector = std::get<std::vector<Elem>>(vectors);
    for ( Elem& e : vector ) {
        fun(x);
    }
}

template <typename Fun>
void ForEach(Fun&& fun) {
    int dummy[] = { 0, (for_each<Ts>(fun), 0)... };
    (void)dummy;
}

要传递一组重载的自由函数,我们可以将它们封装在函数对象中(感谢@Yakk的建议):

struct方法
{
模板
void运算符()(Ts&…Ts)常量
{method(std::forward(ts)…);}
};
在C++1y中,可以使用多态lambda使用较少的样板创建这样的函数对象类型:

[](auto&&... pp)
{ method( std::forward<decltype(pp)>(pp)... ); }
[](自动和…pp)
{method(std::forward(pp)…);}

首先,你应该为你使用的语言添加标签(非常肯定是C++,但我不想假设)第二,解释为什么你不想用语言来解决这个问题?也许是因为作业分配明确地指示你不要这样做?谢谢C++提示。我是舒尔,它在那里,秘密地被解雇了。其次:不,这不是一个家庭作业。只是因为我不喜欢指针。以C++的任何形式。我喜欢保持所有的平面数据。按类型排序通常是性能的好事情。你的<代码>前缀<代码>函数是为了操作所有存储的对象?按顺序排序?是的,对所有存储的对象进行操作,顺序不重要。你可能想要一些类似于代码>模板空洞的东西。(Fun&&Fun);
用于单一类型版本,而
模板void ForEach(Fun&&Fun){int dummy[]={(对于每个(Fun),0)…};(void)dummy;};
用于所有类型版本。这用于具有一组重载
运算符()的函数对象
。谢谢,这是可行的,但我仍然有一些问题。这是可行的:vec.ForEach([](auto t){method(t);});但这不是:vec.ForEach(method);我的意思是两者都可以用()两者都有一个模板参数,为什么第二个失败?@Arne
ForEach
需要为其函数参数推断一个类型。
method
是函数模板的名称;这样的东西没有(唯一的)类型。当您试图传递一组重载函数的名称时,会出现类似的问题。没有重载函数的类型集,只有一个指向特定函数的引用/指针。@Arne lambda表达式具有类类型,我的答案中呈现的多态lambda本质上会导致创建类似
方法\u t lambda表达式就是该类型的实例。
template <typename Elem, typename Fun>
void for_each(Fun&& fun) {
    std::vector<Elem>& vector = std::get<std::vector<Elem>>(vectors);
    for ( Elem& e : vector ) {
        fun(x);
    }
}

template <typename Fun>
void ForEach(Fun&& fun) {
    int dummy[] = { 0, (for_each<Ts>(fun), 0)... };
    (void)dummy;
}
template <typename Elem, typename Fun>
void for_each(Fun fun) {
    std::vector<Elem>& vector = std::get<std::vector<Elem>>(vectors);
    std::for_each(vector.begin(), vector.end(), std::move(fun));
}

template <typename Fun>
void ForEach(Fun fun) {
    int dummy[] = { 0, (for_each<Ts>(fun), 0)... };
    (void)dummy;
}
struct method_t
{
    template<class... Ts>
    void operator()(Ts&&... ts) const
    { method( std::forward<Ts>(ts)... ); }
};
[](auto&&... pp)
{ method( std::forward<decltype(pp)>(pp)... ); }