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_Static_Histogram_Static Polymorphism - Fatal编程技术网

C++ 静态模板类的建议

C++ 静态模板类的建议,c++,templates,static,histogram,static-polymorphism,C++,Templates,Static,Histogram,Static Polymorphism,我有这个问题(历史编程)。我有一个真实的空间:[a,b]以某种方式进行分区([a0=a,a1,a2,…,b])。分区可以具有相等的空间(a1-a0=a2-a1=…)或变量 我需要一个类来处理这个问题,用一些方法来表示给定的值,它属于分区的哪个bin;其他方法可以找到特定箱子的中心等 在这个程序中,我不喜欢实例化一个类,只调用这些简单的函数,比如 Binner binner(binning); binner.get_bin(1.3); binner.get_centerbin(2); 因此,我尝

我有这个问题(历史编程)。我有一个真实的空间:
[a,b]
以某种方式进行分区(
[a0=a,a1,a2,…,b]
)。分区可以具有相等的空间(
a1-a0=a2-a1=…
)或变量

我需要一个类来处理这个问题,用一些方法来表示给定的值,它属于分区的哪个bin;其他方法可以找到特定箱子的中心等

在这个程序中,我不喜欢实例化一个类,只调用这些简单的函数,比如

Binner binner(binning);
binner.get_bin(1.3);
binner.get_centerbin(2);
因此,我尝试使用template编写一个静态类来执行以下操作:

Binner<binning>::get_bin(1.3);
Binner<binning>::get_centerbin(2);
但我认为它太容易出错

以下是我的实施:

enum Binning {CELL, LARGE, BE};
const double binning_LARGE[] = {0, 1.2, 1.425, 1.550, 1.800, 2.5};
const double binning_BE[] =  {0, 1.425, 1.550, 2.5};

template<Binning binning>
class Binner
{
public:
    static const double* bins;
    static const int n;
    static int get_bin(double value);
};

template<> const double* myclass<LARGE>::bins = binning_LARGE;
template<> const double* myclass<BE>::bins = binning_BE;

template<> const int myclass<LARGE>::n = sizeof(binning_LARGE) / sizeof(double);
template<> const int myclass<BE>::n = sizeof(binning_BE) / sizeof(double);

template<Binning binning> int myclass<binning>::get_bin(double value)
{
    return find_if(bins, bins + n,
           bind2nd(greater<double>(), value)) - bins - 1;
}

template<> int myclass<CELL>::get_bin(double value)
{
    return static_cast<int>(value / 0.025);
}
  • 其他/建议
  • 编辑: 关于我不能这样做的第三点:

    template<Binning binning, int N=100>
    class Binner
    {
    public:
        static const double* bins;
        static const int n;
        static int bin(double value);
    };
    
    ...
    
    template<Binning binning, int N> int Binner<CELL, N>::bin(double value)
    {
        return static_cast<int>(value / (2.5 / N));
    }
    
    模板
    班纳
    {
    公众:
    静态常数双*箱;
    静态常数;
    静态整型箱(双值);
    };
    ...
    模板int Binner::bin(双值)
    {
    返回静态_-cast(值/(2.5/N));
    }
    
    <>代码>查找< <代码> FIDIX,如果和 BIDE2以及函数,你似乎对STL和一些高级C++概念很有知识;然而,你试图做的似乎过于工程化了。虽然我不能完全理解您试图做什么,但似乎您可以完全取消模板,只使用一个类(用不同的值实例化)和方法参数。

    IMHO,如果您不想实例化一个类,您的设计是可以的。事实上,对我来说,这似乎是一种幸福。这是否合理取决于您计划如何重用此模板

    当然,使用std::vector将允许您去掉变量以保持数组大小。现在,如果这对你的设计有好处,我不知道。。。它会将模板定义的复杂性转移到binning定义(现在可以非常简单地初始化它)

    最后,您可以实例化模板并向其传递常量:

    template < Binning binning, unsigned long N, unsigned long M>
    class ... {
         <using N>
    }
    
    template
    类。。。{
    }
    
    您考虑过traits类吗?通常,如果您希望将静态信息与类中的行为分离,则可以考虑创建一个封装该类的特性类。p> 因此,我将从默认行为开始:

    enum Binning {CELL, LARGE, BE};
    
    template <Binning binning>
    struct BinTraits
    {
        // default behaviour
        int get_bin(double value) { return value / 0.025; } 
    };
    

    +我也觉得这个设计还可以。但是没有足够的信心说出来。什么是
    N
    ?它是不是
    N=2.5/0.025
    (在我的情况下)?我认为它是一个常数,你想去掉它;它应该是一个长的,比如说25,所以要么把它除以1000,要么在模板声明中定义两个这样长的常量……我不能用不同的模板参数重新声明模板类。现在它是
    bining
    ,我需要它。一个解决方案是使用负枚举值进行可变大小的装箱,使用正枚举值进行相等空间的装箱。关于:
    template
    ?+1,我不知道
    double
    不能是
    template
    参数。看起来是使用模板的一个很好的演示。但我觉得你所做的一切都可以通过选择一个合适的STL容器和定义所需的方法来实现。你的解决方案很好,但我同意“乱穿马路者”的观点:我们已经过度工程化了。
    template < Binning binning, unsigned long N, unsigned long M>
    class ... {
         <using N>
    }
    
    enum Binning {CELL, LARGE, BE};
    
    template <Binning binning>
    struct BinTraits
    {
        // default behaviour
        int get_bin(double value) { return value / 0.025; } 
    };
    
    const double binning_LARGE[] = {0, 1.2, 1.425, 1.550, 1.800, 2.5};
    const double binning_BE[] =  {0, 1.425, 1.550, 2.5};
    
    template <typename RandomAccessCollectionT>
    int get_bin_impl(double value, RandomAccessCollectionT collection, unsigned size)
    {
        return find_if(collection, collection + size,
               bind2nd(greater<double>(), value)) - collection - 1;
    }
    
    template <>
    struct BinTraits<LARGE>
    {
        int get_bin(double value) { return get_bin_impl(value, binning_LARGE, sizeof(binning_LARGE) / sizeof(binning_LARGE[0])); } 
    };
    
    template <>
    struct BinTraits<BE>
    {
        int get_bin(double value) { return get_bin_impl(value, binning_BE, sizeof(binning_BE) / sizeof(binning_BE[0])); } 
    };
    
    template <typename BinTraits>
    class HashTable
    {
    public:
        void insert(double value)
        {
            int bin = BinTraits::get_bin(value);
            _bins[bin].insert(value);
        }
        // _bin is a multimap or something
    };