c++ 属性 实现 wrt getter for struct type 不能自动转换?

c++ Property Implementation wrt getter for struct type cannot be converted automatically?

我正在尝试在 C++ 上实现 属性,这是我的代码: Property.hpp

#ifndef __VIOLET_PROPERTY_H__
#define __VIOLET_PROPERTY_H__

class IProperty
{
protected:
    virtual void init_properties() = 0;
};

#define READ_ONLY 1
#define WRITE_ONLY 2
#define READ_WRITE 3

template <typename Container, typename ValueType, int nPropType>
class property
{
public:
    property()
    {
        m_cObject = NULL;
        Set = NULL;
        Get = NULL;
    }

    //-- Set a pointer to the class that contain the property --
    void setContainer(Container* cObject)
    {
        m_cObject = cObject;
    }

    //-- Set the set member function that will change the value --
    void setter(void (Container::* pSet)(const ValueType& value))
    {
        if ((nPropType == WRITE_ONLY) || (nPropType == READ_WRITE))
            Set = pSet;
        else
            Set = NULL;
    }

    //-- Set the get member function that will retrieve the value --
    void getter(ValueType(Container::* pGet)())
    {
        if ((nPropType == READ_ONLY) || (nPropType == READ_WRITE))
            Get = pGet;
        else
            Get = NULL;
    }

    //-- Overload the = operator to set the value using the set member --
    ValueType operator =(const ValueType& value)
    {
        assert(m_cObject != NULL);
        assert(Set != NULL);
        (m_cObject->*Set)(value);
        return value;
    }

    //-- Cast the property class to the internal type --
    operator ValueType()
    {
        assert(m_cObject != NULL);
        assert(Get != NULL);
        return (m_cObject->*Get)();
    }

private:
    //-- Pointer to the module that contains the property --
    Container* m_cObject;
    //-- Pointer to set member function --
    void (Container::* Set)(const ValueType& value);
    //-- Pointer to get member function --
    ValueType(Container::* Get)();
};

#endif

Source.cpp

#include <iostream>
#include <assert.h>
#include "Property.hpp"
using namespace std;

struct B
{
    B(int _v) { value = _v; }
    int value = 0;

    operator int() {
        return value;
    }
};

class A
{
    B value = 10;
    void setValue(const B& _value)
    {
        value = _value.value;
    }
    B getValue()
    {
        return value;
    }
public:
    A() {
        Value.setContainer(this);
        Value.setter(&A::setValue);
        Value.getter(&A::getValue);
    }
    property<A, B, READ_WRITE> Value;
    operator B() {
        return value;
    }
};

int main()
{
    A a = A();
    B b = a.Value;
    int num = 1 + (B)a.Value + b;
    cout << num << endl;
}

我的问题是为什么我需要为 a.Value 强制设置 (B) 但不能使用像 1+a.Value 这样的隐式转换 我已经为 getter 设置了转换函数,为什么我无法从中获取 ValueType 类型?

    operator ValueType()
    {
        assert(m_cObject != NULL);
        assert(Get != NULL);
        return (m_cObject->*Get)();
    }

尽管如此,如果我无法实现它,是否意味着我将获得更多的显式转换成本? 感谢任何帮助。

您有两个用户定义的转化:

  • a.Value 是一个 property<A,B,READ_WRITE>。它有一个用户定义的转换运算符到 B.
  • B 有一个用户定义的转换运算符到 int

它们不能形成所谓的隐式转换序列,因此您需要先将a.Value显式转换为B。来自 cppreference.com:

Implicit conversion sequence consists of the following, in this order:

1) zero or one standard conversion sequence;

2) zero or one user-defined conversion;

3) zero or one standard conversion sequence.


nevertheless, if i just cannot achieve it, does it mean that i'll get more cost for explicit conversion?

不,优化编译器将其转换为对封装整数的直接访问没有问题。


但是您可以使用转换运算符模板来获得您需要的内容:

#include <iostream>
 
struct Inner {
    int value = 42;
    operator int() const {
        return value;
    }
};
 
struct Outer {
    Inner thing;
    template<typename T>
    operator T() const {
        return thing;  // One implicit conversion sequence here, 
                       // with one user defined conversion (from Inner to int)
    }
};
 
 
int main() {
    Outer b;
    int answer = b; // Another implicit conversion sequence here,
                    // with one user defined conversion (from Outer to int)
    std::cout << answer << std::endl;
}

在您的 A 上使用类似的模板会得到您想要的。