如何编写计算整数和的可变参数模板类的通用版本

中子星

我在此站点上遇到了以下代码(如下)

https://www.modernescpp.com/index.php/c-insights-variadic-templates

但是此声明/定义仅适用于整数,我想编写一个可与​​其他类型(如float,double,std :: strings)和用户定义的类型一起使用的版本,这些类型会重载“ +”运算符。但是我在努力写一篇。

请注意,提到的站点具有基于可变参数函数模板的解决方案,可与包括浮点类型在内的不同数据类型一起使用(尚未尝试使用用户定义的类型)。我正在寻找基于可变参数模板类的解决方案。这纯粹是出于学习目的。

有人可以帮我解决这个问题吗?

#include<iostream>

template<int...>
struct add;

template<>
struct add<>
{
  static constexpr int value = 0;
};

template<int i, int... tail>
struct add<i, tail...>
{
  static constexpr int value = i + add<tail...>::value;
};

int main()
{
    std::cout << add<1,2,3,4>::value;
}

我写了这个但是被卡住了

template<typename ...>
struct add;

template<typename T, typename... args>
struct add<T, args...>
{
    static constexpr T value = ??//T();//what to write here?
};

提前致谢。

AKL

对于非整数类型可以进行一些修改!

模板非类型,非模板参数应为整数类型或具有链接的引用/指针,或者应具有更多限制。可以在此处阅读完整列表模板参数和模板参数

由于浮动类型不能作为非类型模板,非模板参数/参数出现,因此最佳的下一个选择是通过引用获取它们。

因此,struct变为:

template<auto& ...>
struct add{
    static constexpr auto value = 0;
};
template<auto& first, auto& ... others>
struct add<first, others...>{
    static constexpr auto value = first + add<others ...>::value;
};

值应首先存储为常量(带有链接),因此在存储之前main()

const auto v1 = 12; //int
const auto v2 = 54L; //long
const auto v3 = 3.25242; //double
const auto v4 = 75.7256L; //long double

然后可以在以下任何地方使用它们:

#include <iostream>
int main(){
    std::cout << add<v1, v2, v3, v4>::value << std::endl;
}

可能的输出:

144.978

它不仅适用于(混合)整数类型和(混合)浮点类型,而且还适用于任何自定义类型,只要这些自定义类型满足特定的属性(包括具有constexpr构造函数和)即可operator +它还必须具有某种类型转换运算符或其他方式才能实现类似的功能。例如,可以使用以下类型:

class custom_type{
    const float v;
    //this one works too but the first is better for the purpose.
    //float v;
public:
    template<typename T>
    constexpr custom_type(T v_):v(v_){}
    template<typename T>
    constexpr auto operator +(T o)const{
        return o + 7345 + v ;
    }
    //this one works but the next one is  better for the purpose.
    //operator auto()const{
    //this one works too but the next one is more clear.
    //constexpr operator auto()const{
    template<typename T>
    constexpr operator T()const{
        return v;
    }
};

放在一起:

template<auto& ...>
struct add{
    static constexpr auto value = 0;
};
template<auto& first, auto& ... others>
struct add<first, others...>{
    static constexpr auto value = first + add<others ...>::value;
};

class custom_type{
    const float v;
public:
    template<typename T>
    constexpr custom_type(T v_):v(v_){}
    template<typename T>
    constexpr auto operator +(T o)const{
        return o + 7345 + v ;
    }
    template<typename T>
    constexpr operator T()const{
        return v;
    }
};

const auto v1 = 12; //int
const auto v2 = 54L; //long
const auto v3 = 3.25242; //double
const auto v4 = 75.7256L; //long double
const custom_type v5 = 34.234; //custom_type

#include <iostream>
int main(){
    std::cout << add<v1, v2, v3, v4, v5>::value << std::endl;
}

可能的输出:

7524.21

请注意,struct add低于17的C ++版本只能接受单一类型的参数,而该类型double将类似于:

template<const double& ...>
struct add{
    static constexpr double value = 0;
};
template<const double& first, const double& ... others>
struct add<first, others...>{
    static constexpr double value = first + add<others ...>::value;
};

和常量:

const double v1 = 12;
const double v2 = 54L;
const double v3 = 3.25242;
const double v4 = 75.7256l;

祝好运!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章