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
上使用类似的模板会得到您想要的。
我正在尝试在 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
上使用类似的模板会得到您想要的。