如何使用.NET创建泛型类来表示范围?

时间:2021-12-30 19:40:12

I've been trying to make a generic class to represent a range of values but am having some difficulty trying to work out what I'm missing (the compiler comlplains about a missing copy constructor, but all the implementations I've tried have failed). So my questions:

我一直在尝试创建一个泛型类来表示一系列值,但是我在尝试找出我所缺少的内容时遇到了一些困难(编译器对于缺少的复制构造函数进行了解释,但我尝试过的所有实现都失败了)。所以我的问题:

  1. Is there a Range template somewhere I've missed to avoid me reinventing this wheel?
  2. 是否有一个范围模板,我错过了避免我重新发明这个*?

  3. What format does the copy constructor need to be in?
  4. 复制构造函数需要采用什么格式?

  5. Is there anything else I've missed?
  6. 还有什么我错过的吗?

Here's my code as it stands:

这是我的代码:

namespace MyNamespace {
    generic<typename T> public ref class Range
    {
    protected:
        T m_min;
        T m_max;
    public:
        Range(T min, T max)
        {
            m_min = min;
            m_max = max;
        }
        property T Min {
            T get() { return m_min; }
            void set(T min) { m_min = min; }
        }
        property T Max {
            T get() { return m_max; }
            void set(T max) { m_max = max; }
        }
    };

    public ref class MyClass
    {
    protected:
        Range<int> m_myRange;

    public:
        property Range<int> MyRange 
        {
            Range<int> get() { return m_myRange; }
            void set( Range<int> myRange ) { m_myRange = myRange; }
        }
    }
}

The compiler complains about copy constructors in the Range class:

编译器抱怨Range类中的复制构造函数:

1>c:\projects\collections\Range.h(71) : error C2440: 'return' : cannot convert from 'MyNamespace::Range<T>' to 'ZephIRControlsLib::Range<T>'
1>        with
1>        [
1>            T=int
1>        ]
1>        Cannot copy construct class 'MyNamespace::Range<T>' due to ambiguous copy constructors or no available copy constructor
1>        with
1>        [
1>            T=int
1>        ]
1>c:\projects\collections\Range.h(72) : error C2582: 'operator =' function is unavailable in 'MyNamespace::Range<T>'
1>        with
1>        [
1>            T=int
1>        ]
1>.\Range.cpp(8) : error C2512: 'MyNamespace::Range<T>' : no appropriate default constructor available
1>        with
1>        [
1>            T=int
1>        ]

3 个解决方案

#1


Why do you need a range of values?

为什么需要一系列值?

What about using Boost.Range to represent a range within a collection? If you're interested in the min and max only, think std::numeric_limits.

那么使用Boost.Range来表示集合中的范围呢?如果您只对min和max感兴趣,请考虑std :: numeric_limits。

#2


Kill the over engineering and make this a templated struct with 2 public members, min and max. It'll be tons easier to read and you won't have to write a bunch of unit tests for something you can just set directly.

杀死过度工程,并使其成为一个模板化的结构,包含2个公共成员,min和max。这将更容易阅读,你不必为你可以直接设置的东西编写一堆单元测试。

Also seriously consider using the STL paradigm of a half open interval with "begin" and "end". This will actually help range merging make some logical sense for floating point when the ranges are adjacent.

还要认真考虑使用具有“开始”和“结束”的半开区间的STL范例。这实际上有助于范围合并在范围相邻时对浮点具有一定的逻辑意义。

#3


I worked out the missing pieces which seem to work:

我找出了似乎有效的缺失部分:

namespace MyNamespace {
    generic<typename T> public ref class Range
    {
    protected:
        T m_min;
        T m_max;
    public:
        Range()
        {
        }
        Range(T min, T max)
        {
            m_min = min;
            m_max = max;
        }
        Range(Range<RangeType>% rhs)
        {
            m_min = rhs.m_min;
            m_max = rhs.m_max;
        }
        Range% operator=(Range<RangeType>% rhs) 
        {
            m_min = rhs.m_min;
            m_max = rhs.m_max;
            return *this;
        }
        property T Min {
            T get() { return m_min; }
            void set(T min) { m_min = min; }
        }
        property T Max {
            T get() { return m_max; }
            void set(T max) { m_max = max; }
        }
    };

    public ref class MyClass
    {
    protected:
        Range<int> m_myRange;

    public:
        property Range<int> MyRange 
        {
            Range<int> get() { return m_myRange; }
            void set( Range<int> myRange ) { m_myRange = myRange; }
        }
    }
}

#1


Why do you need a range of values?

为什么需要一系列值?

What about using Boost.Range to represent a range within a collection? If you're interested in the min and max only, think std::numeric_limits.

那么使用Boost.Range来表示集合中的范围呢?如果您只对min和max感兴趣,请考虑std :: numeric_limits。

#2


Kill the over engineering and make this a templated struct with 2 public members, min and max. It'll be tons easier to read and you won't have to write a bunch of unit tests for something you can just set directly.

杀死过度工程,并使其成为一个模板化的结构,包含2个公共成员,min和max。这将更容易阅读,你不必为你可以直接设置的东西编写一堆单元测试。

Also seriously consider using the STL paradigm of a half open interval with "begin" and "end". This will actually help range merging make some logical sense for floating point when the ranges are adjacent.

还要认真考虑使用具有“开始”和“结束”的半开区间的STL范例。这实际上有助于范围合并在范围相邻时对浮点具有一定的逻辑意义。

#3


I worked out the missing pieces which seem to work:

我找出了似乎有效的缺失部分:

namespace MyNamespace {
    generic<typename T> public ref class Range
    {
    protected:
        T m_min;
        T m_max;
    public:
        Range()
        {
        }
        Range(T min, T max)
        {
            m_min = min;
            m_max = max;
        }
        Range(Range<RangeType>% rhs)
        {
            m_min = rhs.m_min;
            m_max = rhs.m_max;
        }
        Range% operator=(Range<RangeType>% rhs) 
        {
            m_min = rhs.m_min;
            m_max = rhs.m_max;
            return *this;
        }
        property T Min {
            T get() { return m_min; }
            void set(T min) { m_min = min; }
        }
        property T Max {
            T get() { return m_max; }
            void set(T max) { m_max = max; }
        }
    };

    public ref class MyClass
    {
    protected:
        Range<int> m_myRange;

    public:
        property Range<int> MyRange 
        {
            Range<int> get() { return m_myRange; }
            void set( Range<int> myRange ) { m_myRange = myRange; }
        }
    }
}