Portability of Native C++ properties(本机 C++ 属性的可移植性)
问题描述
在 Visual Studio 中,有 __declspec(property)它创建类似于 C# 的属性.Borland C++ 提供了具有完全相同功能的 __property 关键字.在 C++0x 中,提到了 implicit 关键字,可以扩展以实现相同的功能.但它没有进入规范.
In Visual Studio, there is __declspec(property) which creates properties similar to C#.  Borland C++ offers the __property keyword with the exact same functionality.  In the C++0x, there is mention of a implicit keyword  that could be expanded to implement the same functionality.  But it didn't make it into the spec.
我正在寻找一种可移植且相对干净的方法来声明语法糖化的属性,这些属性将在适用于 Windows、OSX 和 Linux 的最新编译器中进行编译.我不关心编译器兼容性,每个平台只关心一个编译器.
I am looking for a portable and relatively clean method of declaring syntactically sugared properties that will compile in the latest compilers for Windows, OSX and Linux. I am not concerned with compiler compatibility, just one compiler per platform.
我不是在寻找需要括号来获取或设置属性的属性的替代方法,例如分离 getter 和 setter 的重载方法.
I am not looking for alternatives to properties that require parenthesis to get or set the property, such as overloaded methods separating the getters and setters.
这是在 Visual Studio 2010 中编译的理想用法:
Here is an ideal usage which compiles in Visual Studio 2010:
#define _property(_type, _name, _get, _put) __declspec(property(get=_get, put=_put)) _type _name
#define _property_readonly(_type, _name, _get) __declspec(property(get=_get)) _type _name
class Window
{
public:
    _property_readonly(void*, Handle, GetHandle);
    _property(bool, Visible, GetVisible, SetVisible);
    void* GetHandle();
    bool GetVisible();
    void SetVisible(bool);
}
void main()
{
    Window MainWindow;
    if (!MainWindow.Visible)
        MainWindow.Visible = true;
}
推荐答案
这与您要问的类似,并且是(我希望)标准 C++...
This is something similar to what you are asking and is (I hope) standard C++...
#include <iostream>
template<typename C, typename T, T (C::*getter)(), void (C::*setter)(const T&)>
struct Property
{
    C *instance;
    Property(C *instance)
        : instance(instance)
    {
    }
    operator T () const
    {
        return (instance->*getter)();
    }
    Property& operator=(const T& value)
    {
        (instance->*setter)(value);
        return *this;
    }
    template<typename C2, typename T2,
             T2 (C2::*getter2)(), void (C2::*setter2)(const T2&)>
    Property& operator=(const Property<C2, T2, getter2, setter2>& other)
    {
        return *this = (other.instance->*getter2)();
    }
    Property& operator=(const Property& other)
    {
        return *this = (other.instance->*getter)();
    }
};
//////////////////////////////////////////////////////////////////////////
struct Foo
{
    int x_, y_;
    void setX(const int& x) { x_ = x; std::cout << "x new value is " << x << "
"; }
    int getX() { std::cout << "reading x_
"; return x_; }
    void setY(const int& y) { y_ = y; std::cout << "y new value is " << y << "
"; }
    int getY() { std::cout << "reading y_
"; return y_; }
    Property<Foo, int, &Foo::getX, &Foo::setX> x;
    Property<Foo, int, &Foo::getY, &Foo::setY> y;
    Foo(int x0, int y0)
        : x_(x0), y_(y0), x(this), y(this)
    {
    }
};
int square(int x)
{
    return x*x;
}
int main(int argc, const char *argv[])
{
    Foo foo(10, 20);
    Foo foo2(100, 200);
    int x = foo.x; std::cout << x << "
";
    int y = foo.y; std::cout << y << "
";
    foo.x = 42; std::cout << "assigned!
";
    x = foo.x; std::cout << x << "
";
    std::cout << "same instance prop/prop assign!
";
    foo.x = foo.y;
    std::cout << "different instances prop/prop assign
";
    foo.x = foo2.x;
    std::cout << "calling a function accepting an int parameter
";
    std::cout << "square(" << foo.x << ") = " <<  square(foo.x) << "
";
    return 0;
}
正如您从 main 中看到的,只要您分配 T 类型的值(此处为 int)或隐式分配,用法是透明的可转换为 T 到属性,只要您在读取时将它们转换回 T 值.
As you can see from main the usage is transparent as long as you are assigning values of type T (here int) or implicitly convertible to T to properties and as long you are converting them back to T values on reading.
但是,如果您将 foo.x 传递给模板函数,则行为会有所不同,因为 foo.x 的类型不是 int> 但是 Property 代替.
Behavior will be different however if you for example pass foo.x to a template function because the type of foo.x is not int but Property<Foo, int, ...> instead.
您也可能遇到非模板函数的问题...调用接受 T 值的函数将工作正常,但是例如 T& 参数是一个问题,因为基本上该函数要求一个变量直接使用地址访问.出于同样的原因,您当然不能将属性的地址传递给接受 T* 参数的函数.
You can also have problems with non-template functions... calling a function accepting a T value will work fine, however a T& parameter is for example going to be a problem because basically the function is asking a variable to access directly using the address. For the same reason you cannot pass of course the address of a property to a function accepting a T* parameter.
这篇关于本机 C++ 属性的可移植性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:本机 C++ 属性的可移植性
				
        
 
            
        基础教程推荐
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
 - 这个宏可以转换成函数吗? 2022-01-01
 - C++结构和函数声明。为什么它不能编译? 2022-11-07
 - 如何在 C++ 中初始化静态常量成员? 2022-01-01
 - 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
 - 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
 - 常量变量在标题中不起作用 2021-01-01
 - 如何通过C程序打开命令提示符Cmd 2022-12-09
 - 我有静态或动态 boost 库吗? 2021-01-01
 - 在 C++ 中计算滚动/移动平均值 2021-01-01
 
    	
    	
    	
    	
    	
    	
    	
    	
						
						
						
						
						
				
				
				
				