• <bdo id='Gh8di'></bdo><ul id='Gh8di'></ul>

      <tfoot id='Gh8di'></tfoot>
    1. <legend id='Gh8di'><style id='Gh8di'><dir id='Gh8di'><q id='Gh8di'></q></dir></style></legend>

      <small id='Gh8di'></small><noframes id='Gh8di'>

        <i id='Gh8di'><tr id='Gh8di'><dt id='Gh8di'><q id='Gh8di'><span id='Gh8di'><b id='Gh8di'><form id='Gh8di'><ins id='Gh8di'></ins><ul id='Gh8di'></ul><sub id='Gh8di'></sub></form><legend id='Gh8di'></legend><bdo id='Gh8di'><pre id='Gh8di'><center id='Gh8di'></center></pre></bdo></b><th id='Gh8di'></th></span></q></dt></tr></i><div id='Gh8di'><tfoot id='Gh8di'></tfoot><dl id='Gh8di'><fieldset id='Gh8di'></fieldset></dl></div>

        本机 C++ 属性的可移植性

        时间:2023-07-02
          <bdo id='4A6S1'></bdo><ul id='4A6S1'></ul>

          <small id='4A6S1'></small><noframes id='4A6S1'>

            <tbody id='4A6S1'></tbody>
            1. <i id='4A6S1'><tr id='4A6S1'><dt id='4A6S1'><q id='4A6S1'><span id='4A6S1'><b id='4A6S1'><form id='4A6S1'><ins id='4A6S1'></ins><ul id='4A6S1'></ul><sub id='4A6S1'></sub></form><legend id='4A6S1'></legend><bdo id='4A6S1'><pre id='4A6S1'><center id='4A6S1'></center></pre></bdo></b><th id='4A6S1'></th></span></q></dt></tr></i><div id='4A6S1'><tfoot id='4A6S1'></tfoot><dl id='4A6S1'><fieldset id='4A6S1'></fieldset></dl></div>

              • <tfoot id='4A6S1'></tfoot>
                • <legend id='4A6S1'><style id='4A6S1'><dir id='4A6S1'><q id='4A6S1'></q></dir></style></legend>
                  本文介绍了本机 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++ 属性的可移植性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  上一篇:如何将迭代器增加 2? 下一篇:如何在 Windows 上找到 Qt5 CMake 模块

                  相关文章

                    • <bdo id='hE4yZ'></bdo><ul id='hE4yZ'></ul>
                    <legend id='hE4yZ'><style id='hE4yZ'><dir id='hE4yZ'><q id='hE4yZ'></q></dir></style></legend>
                    <tfoot id='hE4yZ'></tfoot>
                    <i id='hE4yZ'><tr id='hE4yZ'><dt id='hE4yZ'><q id='hE4yZ'><span id='hE4yZ'><b id='hE4yZ'><form id='hE4yZ'><ins id='hE4yZ'></ins><ul id='hE4yZ'></ul><sub id='hE4yZ'></sub></form><legend id='hE4yZ'></legend><bdo id='hE4yZ'><pre id='hE4yZ'><center id='hE4yZ'></center></pre></bdo></b><th id='hE4yZ'></th></span></q></dt></tr></i><div id='hE4yZ'><tfoot id='hE4yZ'></tfoot><dl id='hE4yZ'><fieldset id='hE4yZ'></fieldset></dl></div>

                      <small id='hE4yZ'></small><noframes id='hE4yZ'>