2016-09-14 33 views
2

我隔壁班的全自動加CV-合格的功能

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認證版本。可能?

+0

你經常使用'常量volatile'對象?我從來沒有見過。 –

+1

你可能想寫一個簡單的代碼生成器。 – Arun

+0

我用宏做了類似的事情。 –

回答

1

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

#define IDK_WHY(returnType, functionName, functionArgs, functionBody) \ 
        returnType functionName functionArgs    functionBody \ 
    volatile  returnType functionName functionArgs volatile  functionBody \ 
    const   returnType functionName functionArgs const   functionBody \ 
    const volatile returnType functionName functionArgs volatile const functionBody 

class Parameter 
{ 
    using T = int; //for testing, dunno what is T in your code 
private: 
    T value_; 

public: 
    // note you can't use comma in last argument, it would require more complex macro 
    IDK_WHY(T&, value,(), { return value_;}) //done 
}; 
+0

醜。但有效。就像C.最快的解決方案一樣。我不喜歡它,但使用。謝謝。 – kyb

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()語法,禁止醜陋的宏。

+0

可以準確地說C++ std需要這個代碼嗎?任何GCC擴展? – kyb

+0

@kyb據我所知,我只是使用了bog標準的C++ 14。可能會有錯別字。是的,我在'operator - > *'上錯過了一個'friend'。注意,'(p - > * value)()'語法假定你已經實現了上面的'get_value':它只是爲你調用'get_value'的語法糖(我不確定糖有多甜)。 – Yakk

+0

謝謝你的詳細答案,但它不是我想要達到的。 – kyb

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; 
}