2016-09-14 4 views
2

У меня есть следующий классAutomaticly добавить резюме квалифицированных функции

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 с правом квалификации л/г/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, насколько я могу судить, я просто использовал болото стандартное C++ 14. Там могут быть опечатки. Да, я пропустил 'friend' на' operator -> * '. Обратите внимание, что синтаксис '(p -> * value)()' предполагает, что вы уже реализовали 'get_value' выше: это просто синтаксический сахар, чтобы вызывать' get_value' для вас (и я не уверен, насколько сладок сахар). – Yakk

+0

Благодарим вас за подробный ответ, но это не то же самое, чего я хочу достичь. – kyb

2

Другим решением может быть использование макросов. Возможно, он менее изящный, но он очень простой, понятный и мощный.

Вы можете определить макрос, просто используя имя переменной-члена и записывая каждый геттер (вы можете взорвать это с помощью 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; 
} 
Смежные вопросы