【问题标题】:argument of type * is incompatible with parameter of type "const float *"* 类型的参数与 \"const float *\" 类型的参数不兼容
【发布时间】:2023-02-07 04:47:26
【问题描述】:

我是 C++ 的新手。我进行了广泛的搜索,但我无法让它发挥作用,甚至上帝也没有……我的意思是,ChatGPT 设法帮助了我。

我定义了一个名为“vec_t”的自定义类型。

class FloatType {
        private:
            float value;
        public:
            FloatType() : value(0.0f) {}
            FloatType(float v) : value(v) {}

            //operator float() { return value; }
            //operator float() { return value; }
            //explicit operator const float* () { return &value; }
            //operator float* () const { return &value; }
            //operator const float* () { return &value; }
            //operator const float() { return (const float)value; }
            //operator const float*() { return &value; }
}

typedef FloatType vec_t;

我还创建了一个将 const float * 作为唯一参数的函数。

void Create(const float* vColor = NULL);
void Create(const float* vColor) {
    //...
}

现在,当像这样调用函数时......

vec_t a = { 2.5f };
vec_t* b = &a;
Create(b);

...Visual Studio Community 2019 (v142) 正在抱怨argument of type "vec_t *" is incompatible with parameter of type "const float *"

现在,当场将其转换为“const float *”即可完成:

Create((const float *)b);

但是,我的目标是有一个隐式转换运算符来从我的类型隐式转换为“const float *”,但是,无论我如何努力,我似乎​​都无法做到。

所有operator cmets 都是我的尝试,它们都有有效的语法,但它们并没有使问题消失。

我不明白什么?

我希望能够从 FloatType 类本身内部处理这个问题,据我所知,隐式转换运算符是这样做的方法。不要指导我使用其他方法,这纯粹是为了练习和锻炼。

提前致谢。

【问题讨论】:

  • 传递 a 而不是 b,您的操作员就会工作。
  • 现在,当场将其转换为“const float *”即可完成:“:不,这会导致未定义的行为。它只是看起来有效。不要在 C++ 中使用像这样的 C 样式转换。你最终会像你在这里做的那样导致未定义的行为。
  • 实际上,在这种非常特殊的情况下,您的演员表是有效的。 (您的班级恰好是标准布局。)然而,我所说的确实适用于一般情况。

标签: c++ c++17


【解决方案1】:

您的类型不是指针,因此您不应使用指针作为Create 的参数。

class FloatType 
{
private:
    float value;
public:
    ...
    operator const float* () const { return &value; }
        // const needed here ^^^^^
};

typedef FloatType vec_t;

vec_t a = { 2.5f };
Create(a);

出于某种原因,您引入了指针b,这是您的代码不起作用的主要原因。正如我在上面指出的那样,您还需要在转换运算符上添加一个额外的 const

【讨论】:

  • @user17732522 显然不是。但我认为最好回答所提出的问题。 OP 将在准备就绪时了解良好的设计。
【解决方案2】:

问题在于,虽然 vec_t 是可以定义转换运算符的类类型,但 vec_t * 是原始类型(指针),并且没有用户定义的转换适用于它。

一些可能的解决方案:

  • 不要传递指向vec_t 的指针,而是按值传递它们。如有必要,请使用std::move 以避免可能昂贵的副本。这归结为Create(a)。约翰的回答更详细地解释了这一点。
  • 取消引用指针,如Create(*b),以允许编译器找到您的用户定义的转换。
  • vec_t添加一个float * data()成员函数,就像std::vector一样,调用它获取底层数据:Create(b->data())
  • 不要使用自己的矢量类型并且只需使用 std::array<float, N> 来表示静态大小的向量,使用 std::vector<float> 来表示动态大小的向量。这可能是最好的解决方案。要获取指向原始数据的指针,请使用vec.data()。 (同样,利用这些类型的值语义来获得内存安全。移动/复制它们,不要使用原始指针。)
  • 如果你想要一些你不应该做的非常丑陋的事情:Create(b->operator float *())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-08
    • 1970-01-01
    • 2021-08-06
    • 2020-11-19
    • 2019-12-16
    • 2016-05-19
    • 1970-01-01
    相关资源
    最近更新 更多