Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.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_C++11 - Fatal编程技术网

C++ 特定积分常数的重载比较

C++ 特定积分常数的重载比较,c++,templates,c++11,C++,Templates,C++11,我正在将一大组地理空间代码从一个投影转换为另一个投影。为了在转换过程中强制使用适当的单位,我引入了距离、点、矩形和多边形模板,这些模板使用一个标记来指示使用的坐标系。这是一个很好的解决方案,但是在很多地方,对非零(!=0)或正值(>0)执行检查。我希望能够重载这些运算符,以允许与0进行比较,而不与任何其他数字进行比较。有可能做到这一点吗 作为一个额外的限制,我不能使用constexpr,因为我必须支持VS 2013,但我仍然想知道是否有办法使用constexpr 仅供参考,我正在处理以下内容:

我正在将一大组地理空间代码从一个投影转换为另一个投影。为了在转换过程中强制使用适当的单位,我引入了距离、点、矩形和多边形模板,这些模板使用一个标记来指示使用的坐标系。这是一个很好的解决方案,但是在很多地方,对非零(
!=0
)或正值(
>0
)执行检查。我希望能够重载这些运算符,以允许与
0
进行比较,而不与任何其他数字进行比较。有可能做到这一点吗

作为一个额外的限制,我不能使用
constexpr
,因为我必须支持VS 2013,但我仍然想知道是否有办法使用
constexpr

仅供参考,我正在处理以下内容:

template<typename Tag> struct Distance
{
  int value;
};

template<typename Tag> struct Point
{
  Distance<Tag> x;
  Distance<Tag> y;
};

// This works fine for comparing two Distances
template<typename Tag> bool operator>(const Distance<Tag>& a, const Distance<Tag>& b) {return a.value > b.value;}
// But I don't want this to allow a > 14, only a > 0
template<typename Tag> bool operator>(const Distance<Tag>& a, int b) {return a.value > b;}

struct Mercator;
typedef Point<Mercator> MercPoint;
struct GuiScale;
typedef Point<GuiScale> GuiPoint;
// etc.
模板结构距离
{
int值;
};
模板结构点
{
距离x;
距离y;
};
//这适用于比较两个距离
模板布尔运算符>(常量距离&a,常量距离&b){返回a.value>b.value;}
//但我不希望这允许a>14,只允许a>0
模板布尔运算符>(常量距离&a,int b){返回a.value>b;}
结构墨卡托;
typedef Point MercePoint;
结构尺度;
typedef点GuiPoint;
//等等。

您可以使用
nullptr\t
作为一种攻击(作为literal
0
转换为
nullptr
):

模板布尔运算符>(常量距离&a,std::nullptr_t b){返回a.value>0;}

您可以使用
nullptr\t
作为一种攻击(作为literal
0
转换为
nullptr
):

模板布尔运算符>(常量距离&a,std::nullptr_t b){返回a.value>0;}

您可以使用到文字零的任何指针的转换:

#include <type_traits>

template<typename Tag>
struct Distance
{
private:
    using literal_zero = void(Distance::*)();

    template<typename U>
    using enable_nullptr = typename std::enable_if<
        std::is_same< typename std::decay< U >::type, std::nullptr_t >::value
    >::type;

public:
    int value;

    bool operator<( literal_zero ) const { return value < 0; }

    template<typename U>
    enable_nullptr<U> operator<( const U& ) const = delete;
};

int main() {
    Distance<int> a;
    a.value = 0;

    a < 0;
    // a < 42; // does not compile
    // a < nullptr; // does not compile
}
#包括
样板
结构距离
{
私人:
使用literal_zero=void(距离::*)();
样板
使用enable_nullptr=typename std::enable_if<
std::is_same:type,std::nullptr_t>:value
>::类型;
公众:
int值;

bool运算符您可以使用到文本零的任何指针的转换:

#include <type_traits>

template<typename Tag>
struct Distance
{
private:
    using literal_zero = void(Distance::*)();

    template<typename U>
    using enable_nullptr = typename std::enable_if<
        std::is_same< typename std::decay< U >::type, std::nullptr_t >::value
    >::type;

public:
    int value;

    bool operator<( literal_zero ) const { return value < 0; }

    template<typename U>
    enable_nullptr<U> operator<( const U& ) const = delete;
};

int main() {
    Distance<int> a;
    a.value = 0;

    a < 0;
    // a < 42; // does not compile
    // a < nullptr; // does not compile
}
#包括
样板
结构距离
{
私人:
使用literal_zero=void(距离::*)();
样板
使用enable_nullptr=typename std::enable_if<
std::is_same:type,std::nullptr_t>:value
>::类型;
公众:
int值;

bool运算符如果与literal
0
进行比较在语义上是有效的,则允许从literal
0
进行转换也是有效的。转换到位后,不需要特殊情况比较():

模板结构距离
{
int值;
距离()=默认值;
显式constexpr距离(int v):值(v){}
constexpr距离(std::nullptr_t):值(0){
friend constexpr bool运算符==(常量距离和左侧、常量距离和右侧){
返回lhs.value==rhs.value;
}
friend constexpr布尔运算符<(const Distance&lhs、const Distance&rhs){
返回lhs.value
如果与文字
0
进行比较在语义上是有效的,那么允许从文字
0
进行转换也是有效的。转换到位后,不需要特殊情况比较():

模板结构距离
{
int值;
距离()=默认值;
显式constexpr距离(int v):值(v){}
constexpr距离(std::nullptr_t):值(0){
friend constexpr bool运算符==(常量距离和左侧、常量距离和右侧){
返回lhs.value==rhs.value;
}
friend constexpr布尔运算符<(const Distance&lhs、const Distance&rhs){
返回lhs.value
为什么不使用布尔函数,如
IsZero
?在我看来,重载只取1个允许值的数学运算符是个坏主意。距离
类模板的意义是什么?@P0W,因此不能给
运算符>
(或另一个函数)提供两个不相关的距离并给整数类型一个与其用途相对应的名称。签出这些:这些类型是中间转换步骤的一部分,还是应该保留为最终形式?如果代码要保留这些类型,我将重构为命名函数(
.isZero()
isPositive()
)…但如果类型只是暂时的,那么这可能需要更多的工作为什么不使用bool函数,例如
IsZero
?在我看来,重载只取1个允许值的数学运算符是个坏主意。
距离
类模板@P0W有什么意义,所以你不能给
运算符>
(或另一个函数)并为整数类型指定与其用途相对应的名称。签出这些:这些类型是中间转换步骤的一部分,还是应该保留为最终形式?如果代码要保留这些类型,我将重构为命名函数(
.isZero()
isPositive()
)…但是如果类型只是暂时的,这可能是更多的工作。我没有想到这种转换。这看起来像是要走的路。谢谢!我没有想到这种转换。这看起来像是要走的路。谢谢!我只是想说清楚。我只是想说清楚。
template<typename Tag> struct Distance
{
  int value;

  Distance() = default;
  explicit constexpr Distance(int v) : value(v) {}
  constexpr Distance(std::nullptr_t) : value(0) {}

  friend constexpr bool operator == (const Distance& lhs, const Distance& rhs) {
    return lhs.value == rhs.value;
  }
  friend constexpr bool operator < (const Distance& lhs, const Distance& rhs) {
    return lhs.value < rhs.value;
  }
  // ...
};