3

**我有一些建议可以使我的函数成为纯通用的,这会起作用,但我更愿意将函数限制为仅接受 Base 及其子级。

在创建一个可以接受可变参数模板类基类型参数的函数时遇到问题,而该函数实际上将使用派生自 Base 的类调用。我已经尝试了几件事。这是一般的想法。鉴于:

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_together 函数的变体,但都不起作用。保持上述状态会生成有关缺少模板参数的编译器错误。我不确定如何将定义 DerivedA 和 DerivedB 的模板参数传递给函数。

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

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

4 回答 4

4

编辑:

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

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);
}

这是有效的,因为参数包是从参数推断出来的,而不是在列表中指定的。自然不能有一个依赖于多个参数包的类。

于 2010-09-08T19:43:29.870 回答
2

当你写:string moosh_together(Base A, Base B)时,问问自己是什么BaseBase类模板,而不是类类型。

换句话说,给定:

template <typename T>
struct foo {};

foo<int>并且foo<float>是两种完全不同的类型,恰好是由同一个类模板制成的。它们没有共同的基类,你不能简单地引用它们,就像foo你不能同时引用它们intfloat单一类型一样。

您可以将 的非依赖部分排除在外Base

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);

并说“如果你有必要的成员,你可以使用这个功能”。

于 2010-09-08T19:40:02.613 回答
1

您不能在继承层次结构中创建一个基类Base并将其传递给moosh_together()函数吗?(这里对c++的了解不多)

于 2010-09-08T19:26:21.937 回答
1

我认为这个的一般扩展是

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...);
}
于 2010-09-08T20:45:53.910 回答