C ++运算符歧义 [英] C++ Operator Ambiguity

查看:80
本文介绍了C ++运算符歧义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请原谅我,因为我对C ++还是很陌生,但是在操作符歧义方面遇到了一些麻烦.我认为它是特定于编译器的,用于在我的桌面上编译的代码.但是,它无法在我的笔记本电脑上编译.我想我知道出了什么问题,但是我看不出有什么优雅的解决方法.如果我犯了一个明显的错误,请让我知道.无论如何,这就是我想要做的:

Forgive me, for I am fairly new to C++, but I am having some trouble regarding operator ambiguity. I think it is compiler-specific, for the code compiled on my desktop. However, it fails to compile on my laptop. I think I know what's going wrong, but I don't see an elegant way around it. Please let me know if I am making an obvious mistake. Anyhow, here's what I'm trying to do:

我制作了自己的向量类Vector4,它看起来像这样:

I have made my own vector class called Vector4 which looks something like this:

class Vector4
{
 private:
   GLfloat vector[4];
 ...
}

然后我有了这些引起问题的运算符:

Then I have these operators, which are causing the problem:

operator GLfloat* () { return vector; }

operator const GLfloat* () const { return vector; }

GLfloat& operator [] (const size_t i) { return vector[i]; }

const GLfloat& operator [] (const size_t i) const { return vector[i]; }

我有转换运算符,因此我可以将Vector4类的实例传递给glVertex3fv,并且出于明显的原因,我有下标.但是,涉及对Vector4进行下标的调用对于编译器来说是模棱两可的:

I have the conversion operator so that I can pass an instance of my Vector4 class to glVertex3fv, and I have subscripting for obvious reasons. However, calls that involve subscripting the Vector4 become ambiguous to the compiler:

enum {x, y, z, w}
Vector4 v(1.0, 2.0, 3.0, 4.0);

glTranslatef(v[x], v[y], v[z]);

以下是候选人:

candidate 1: const GLfloat& Vector4:: operator[](size_t) const
candidate 2: operator[](const GLfloat*, int) <built-in>

为什么在Vector4上已经定义了下标运算符时,为什么它会首先尝试将我的Vector4转换为GLfloat *?有没有解决此问题的简单方法,该方法不涉及类型转换?我是在犯一个愚蠢的错误吗?感谢您的任何事先帮助.

Why would it try to convert my Vector4 to a GLfloat* first when the subscript operator is already defined on Vector4? Is there a simple way around this that doesn't involve typecasting? Am I just making a silly mistake? Thanks for any help in advance.

推荐答案

这本书在"C ++模板-完整指南"中进行了解释.这是因为您的operator []占用了size_t,但是您传递了一个不同的类型,该类型首先必须进行隐式转换为size_t.另一方面,也可以选择转换运算符,然后返回的指针可以是下标.因此存在歧义.解决方案是删除转换运算符.如您所见,通常应避免使用它们,因为它们只会带来问题.

This is explained in the book "C++ Templates - The Complete Guide". It's because your operator[] takes size_t, but you pass a different type which first has to undergo an implicit conversion to size_t. On the other side, the conversion operator can be chosen too, and then the returned pointer can be subscript. So there is the ambiguity. Solution is to drop the conversion operator. They should generally be avoided as they just introduce problems, as you see.

提供一个beginend成员函数,分别返回vectorvector + 4.然后,如果要传递给本机openGL函数,则可以使用v.begin().

Provide a begin and end member function that returns vector and vector + 4 respectively. Then you can use v.begin() if you want to pass to native openGL functions.

评论中有些混乱.我认为我现在将更新此答案以反映此问题的最新概念.

There is a bit confusion in the comments. I think i will update this answer now to reflect the most recent concept of this.

struct Vector4 {
    // some of container requirements
    typedef GLfloat value_type;
    typedef GLfloat& reference;
    typedef GLfloat const& const_reference;

    typedef GLfloat * iterator;
    typedef GLfloat const * const_iterator;

    typedef std::ptrdiff_t difference_type;
    typedef std::size_t size_type;

    static const size_type static_size = 4;

    // returns iterators to the begin and end
    iterator begin() { return vector; }
    iterator end() { return vector + size(); }

    const_iterator begin() const { return vector; }
    const_iterator end() const { return vector + size(); }

    size_type size() const { return static_size; }
    size_type max_size() const { return static_size; }

    void swap(Vector4 & that) {
        std::swap(*this, that);
    }

    // some of sequences
    reference operator[](size_type t) { return vector[t]; }
    const_reference operator[](size_type t) const { return vector[t]; }

    // specific for us. returns a pointer to the begin of our buffer.
    // compatible with std::vector, std::array and std::string of c++1x
    value_type * data() { return vector; }
    value_type const* data() const { return vector; }

    // comparison stuff for containers
    friend bool operator==(Vector4 const&a, Vector4 const&b) {
        return std::equal(a.begin(), a.end(), b.begin());
    }
    friend bool operator!=(Vector4 const&a, Vector4 const&b) { return !(a == b); }
    friend bool operator<(Vector4 const&a, Vector4 const&b) {
        return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
    }
    friend bool operator> (Vector4 const&a, Vector4 const&b) { return b < a;    }
    friend bool operator<=(Vector4 const&a, Vector4 const&b) { return !(b < a); }
    friend bool operator>=(Vector4 const&a, Vector4 const&b) { return !(a < b); }

private:
    GLfloat vector[4];
}

这篇关于C ++运算符歧义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆