自动添加CV限定功能

时间:2016-09-14 19:45:40

标签: c++ parameters

我有下一堂课

class Parameter
{
private:
    T value_;

public:
    // Get
    T& value()                                 { return value_; }
    volatile T& value() volatile               { return value_; }
    const T& value() const                     { return value_; }
    const volatile T& value() volatile const   { return value_; }
}

如何最小化行数,代码量。我想写一次T& value()并自动获得CV资格版本。可能的?

3 个答案:

答案 0 :(得分:3)

如果要公开对变量的每个引用,请公开变量。

现在p.value_完全符合您的要求。

除此之外,最简单的方法是写:

template< class A, class B >
using same_test = std::enable_if_t< std::is_same< std::decay_t<A>, std::decay_t<B> >{}, int>

然后在课堂内写:

template<class Self, same_test<Self, Parameter> =0>
friend decltype(auto) get_value( Self&& self ) {
  return decltype(self)(self).value_;
}

现在get_value( p )将返回p.value并具有正确的l / r / cv资格。

如果您不喜欢这种语法,我可以为您提供(p->*value)()

template<class F>
struct magic_method_ptr_t {
  F f;
  template<class Lhs>
  friend auto operator->*(Lhs&& lhs, magic_method const& m) {
    return [&](auto&&...args)->decltype(auto) {
      return m.f( decltype(lhs)(lhs), decltype(args)(args)... );
    };
  }
};
template<class F>
magic_method_ptr_t<F> magic_method_ptr( F f ) { return {std::move(f)}; }

auto value = magic_method_ptr( [](auto&& x){ return get_value(decltype(x)(x)); }

将其添加到上面的get_value案例中,(p->*value)()可以使用。

我无法为您提供p.value()语法,禁止使用丑陋的宏。

答案 1 :(得分:2)

另一种解决方案可能是使用宏。也许不那么优雅,但它非常简单,清晰而有力。

您可以定义一个宏,只需获取成员变量名称并编写每个getter(您也可以使用setter和其他实用程序将其爆炸)。

/// @param X is the variable name
/// @param Y is the get name. The result will be get_##Y
#define create_getters(X, Y) decltype(X)& get_##Y() {   \
    return this->X; \
  } \
  const decltype(X)& get_##Y() const { \
    return this->X; \
  }

// Example class
class Foo {
  std::string m_data;

 public:
  // expose m_data as get_Data()
  create_getters(m_data, Data);  // Actually you don't need ; here
};

int main(int argc, char *argv[]) {
  Foo f;
  auto&& r = f.get_Data();  // ref
  auto&& cr = static_cast<const Foo&>(f).get_Data();  // const-ref

  return 0;
}

答案 2 :(得分:1)

是的,你可以使用宏,但我看不到任何使用这些:

left: 760px;