gpt4 book ai didi

c++ - 仅更改一个成员函数的类模板特化

转载 作者:搜寻专家 更新时间:2023-10-31 01:33:23 25 4
gpt4 key购买 nike

我有一个类模板 Function,它接受一个无符号整数作为模板参数,用于输入的数量。此模板重载 operator(),因此可以针对一组给定的输入评估 Function

通常,该成员的原型(prototype)之一是operator()(double, ...)。但是,如果模板参数为 0,则该原型(prototype)将不起作用,因为它至少需要一个参数。

template <unsigned Arity>
struct Function {
void operator () (double, ...);
};

通常,我只会编写一个模板特化,但会有很多很多 冗余代码,因为还有很多其他成员函数。同样,通常情况下,我会创建一个基类,其中包含用于主类定义和要继承的特化的冗余代码。

struct FunctionBase {
// Common code
Function operator + (Function const &) const; // ?
};

template <unsigned Arity>
struct Function : FunctionBase { /* etc */ };

不幸的是,我不确定该怎么做,因为例如 operator+ 意味着返回一个 Function。但是,如果 Function 只是稍后定义的,它怎么能做到这一点呢? Function继承自基类,这样设计operator+在基类中...

它可以返回基类的一个实例,但是我们需要一种方法将该实例转换为 Function 的实例,我知道如果不复制第一个实例的实例就无法做到这一点数据,这在性能方面非常昂贵。

我怎样才能做到这一点?

最佳答案

这个问题很难回答,因为它远未明确。
以下两个可能的替代方案试图解决您的问题:

  • 如果你想继续 Arity 模板参数,你可以使用 sfinae'd operators 来处理 Arity 等于 0:

    #include<iostream>

    template<int Arity>
    struct Function {
    template<int N = Arity>
    std::enable_if_t<N == 0> operator()() {
    std::cout << "arity == 0" << std::endl;
    }

    template<int N = Arity>
    std::enable_if_t<N != 0> operator()(double, ...) {
    std::cout << "arity != 0" << std::endl;
    }
    };

    int main() {
    Function<0> f1;
    Function<2> f2;

    f1();
    f2(0., 42);
    }

    这样您就不再需要引入基类,所有相关问题也不再适用。

  • 如果您介意改变方法,您可以为您的函数对象切换到以下模式:

    template<typename>
    struct Function;

    template<typename R, typename... A>
    struct Function<R(A...)> {
    R operator()(A... args) {
    // ...
    }

    // ...
    };

    您可以按如下方式使用它:

    Function<void(int, char)> f;

    如果你想有一个固定的double作为operator()的第一个参数,你可以这样做:

    template<typename R, typename... A>
    struct Function<R(double, A...)> {
    R operator()(double d, A... args) {
    // ...
    }

    // ...
    };

    并按如下方式使用它:

    Function<void(double, int, char)> f1;
    Function<void(double)> f1;

    这至少有助于轻松处理空参数包(请注意,sizeof...(A) 将在任何情况下向您返回提交参数的数量)。

    它遵循一个最小的、有效的示例实现:

    #include<iostream>

    template<typename>
    struct Function;

    template<typename R, typename... A>
    struct Function<R(A...)> {
    R operator()(A... args) {
    int _[] = { 0, (std::cout << args << std::endl, 0)... };
    (void)_;
    }

    template<typename... O>
    Function<R(A..., O...)> operator+(Function<R(O...)>) {
    return {};
    }

    // ...
    };

    int main() {
    Function<void(int)> f1;
    Function<void(double)> f2;

    f1(42);
    f2(0.);
    (f1+f2)(3, .3);
    }

关于c++ - 仅更改一个成员函数的类模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41514405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com