在clang和gcc中,是否存在可视C ++ __declspec(属性声明属性)的替代方法?

Ite*_*tor 4 c++ gcc clang visual-c++

有一个Microsoft特定的扩展名,它使得可以这样定义属性获取器和设置器:

// declspec_property.cpp
struct S {
   int i;
   void putprop(int j) {
      i = j;
   }

   int getprop() {
      return i;
   }

   __declspec(property(get = getprop, put = putprop)) int the_prop;
};

int main() {
   S s;
   s.the_prop = 5;
   return s.the_prop;
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以使用clang或gcc定义属性声明属性?如果我搜索__declspec,我发现的只是__declspec(dllexport),但我没有在寻找。

dar*_*une 8

有支持

请参阅我的示例:https : //godbolt.org/z/PobB_3

尽管您必须使用-fdeclspec或打开它-fms-extensions


Mos*_*ieb 6

尽管C ++不提供对智能可重写运算符的支持(并且没有gcc扩展),但该语言允许您使用其现有功能来实现它。
以下示例(并非假定涵盖所有情况!)显示了使用本机C ++ 11或更高版本的可能解决方案。
我们可以使用虚拟覆盖来覆盖属性,但这不是现代智能属性在其他语言(如swift,C#等)中的工作方式,因此-我正在使用lambda注入用于setter和getter的覆盖代码。

// The following is by no means a FULL solution!
#include <functional>
#include <iostream>
#include <cassert>

template<typename T> 
class Property {
public:
    Property(){}
    operator const T& () const {
        // Call override getter if we have it
        if (getter) return getter();
        return get();
    }
    const T& operator = (const T& other) {
        // Call override setter if we have it
        if (setter) return setter(other);
        return set(other);
    }
    bool operator == (const T& other) const {
        // Static cast makes sure our getter operator is called, so we could use overrides if those are in place
        return static_cast<const T&>(*this) == other;
    }
    // Use this to always get without overrides, useful for use with overriding implementations
    const T& get() const {
        return t;
    } 
    // Use this to always set without overrides, useful for use with overriding implementations
    const T& set(const T& other) {
        return t = other;
    }
    // Assign getter and setter to these properties
    std::function<const T&()> getter;
    std::function<const T&(const T&)> setter;
private:
    T t;
};

// Basic usage, no override
struct Test {
    Property<int> prop;
};

// Override getter and setter
struct TestWithOverride {
    TestWithOverride(){
        prop.setter = [&](const int& other){
            std::cout << "Custom setter called" << std::endl;
            return prop.set(other);
        };
        prop.setter = std::bind(&TestWithOverride::setProp,this,std::placeholders::_1);
        prop.getter = std::bind(&TestWithOverride::getProp,this);
    }
    Property<int> prop;
private:
    const int& getProp() const {
        std::cout << "Custom getter called" << std::endl;
        return prop.get();
    }
    const int& setProp(const int& other){
        std::cout << "Custom setter called" << std::endl;
        return prop.set(other);
    }
};

int main(int,char**){
    Test t;
    TestWithOverride t1;
    t.prop = 1;
    assert(t.prop == 1);
    t1.prop = 1;
    assert(t1.prop == 1);
    /*
    Expected output:
    1. No aborts on assertions
    2. Text:
    Custom setter called
    Custom getter called
    */
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译如下:
c++ -std=c++11 test.cpp -o test
运行:
./test