代码之家  ›  专栏  ›  技术社区  ›  Brett Rossier

将可变类模板的子类传递给只接受基类的函数(通过参数包推断)

  •  3
  • Brett Rossier  · 技术社区  · 15 年前

    在生成一个可以接受可变模板类基类型参数的函数时遇到困难,而该函数实际上将使用从基派生的类调用。我试过一些方法。大致思路是这样的。鉴于:

    template<typename... Args> struct Base {
        std::tuple<Args...> data;
        ... //other stuff
    };
    
    struct DerivedA : Base<string, int> {
    };
    
    struct DerviedB : Base<bool, string, int> {
    };
    

    创建函数的正确方法是什么:

    string moosh_together(Base A, Base B) { //I only need access to Base's members
        return get<0>(A.data) + get<1>(B.data);
    }
    
    main() {
        DerivedA aThing;
            get<0>(aThing.data) = "foo";
        DerivedB bThing;
            get<1>(bThing.data) = "bar'd";
        cout << moosh_together(aThing, bThing) << endl;
    }
    

    输出:

    foobar'd
    

    我尝试过mooshèu together函数的一些变体,但都不起作用。保持上述状态会生成一个关于缺少模板参数的编译器错误。我不确定如何将定义DerivedA和DerivedB的模板参数传递给函数。

    我试过的其他方法(散弹枪法):

    string moosh_together(Base<> A, Base<> B) {}
    //err: conversion from 'DerivedA' to non-scalar type 'Base<>' requested
    
    template<Base<typename... Args> T1, Base<typename... Args> T2>
    string moosh_together(T1 A, T2 B) {}
    //err: expected paramter pack before '...'
    
    template<Base<Args...> T1, Base<Args...> T2>
    string moosh_together(T1 A, T2 B) {}
    //err: 'Args' was not declared in this scope
    
    4 回复  |  直到 14 年前
        1
  •  4
  •   Jon Purdy    15 年前

    编辑:

    如果您需要这两个参数包,您可以将它们都放在模板规范中:

    template<typename... ArgsA, typename... ArgsB>
    string moosh_together(const Base<ArgsA...>& A, const Base<ArgsB...>& B) {
        return get<0>(A.data) + get<1>(B.data);
    }
    

        2
  •  2
  •   GManNickG    15 年前

    当你写: string moosh_together(Base A, Base B) 问自己什么 Base 是。 是一个 类模板

    换句话说,假设:

    template <typename T>
    struct foo {};
    

    foo<int> foo<float> 是两种完全不同的类型,恰好是由同一个类模板生成的。它们没有公共基类,您不能将它们简单地称为 foo int float 只有一种类型。

    你可以算出 底座 :

    struct Core
    {
        string name;
    };
    
    template <typename... Args>
    struct Base : Core
    {
        // ...
    };
    

    然后参考 Core 部分:

    // pass by reference, to avoid unnecessary copying
    string moosh_together(const Core& a, const Core& b);
    

    或者让函数完全通用:

    template <typename BaseOne, typename BaseTwo>
    string moosh_together(const BaseOne& a, const BaseTwo& b);
    

        3
  •  1
  •   Zachary Yates    15 年前

    不能在继承层次结构中为创建基类吗 Base 把它传给 moosh_together() 功能?(这里的c++知识水平较低)

        4
  •  1
  •   Johannes Schaub - litb    15 年前

    string moosh_together(Base<T1...> A1, Base<T2...> A2, ... Base<Tn...> An) {
        return get<0>(A1.data) + get<1>(A2) + ... + get<n-1>(An.data);
    }
    

    可以这样写

    template<int I> 
    string moosh_together() { return ""; }
    
    template<int I, typename ...Base1Ty, typename ... Bases>
    string moosh_together(Base<Base1Ty...> const& base1, Bases const&... bases) {
        return get<I>(base1.data) + moosh_together<I+1>(bases...); 
    }
    
    template<typename ... Bases>
    string moosh_together(Bases const&... bases) {
        return moosh_together<0>(bases...);
    }