Re[2]: default arguments in typedef declarations
От: Evgeny.Panasyuk Россия  
Дата: 22.02.13 01:20
Оценка: 96 (1)
Здравствуйте, Кодт, Вы писали:

К>Чисто в качестве альтернативы — совершенно не уверен, что это решает искомую задачу, но просто для иллюстрации, что так можно делать — введём не один, а два указателя рядом

К>
К>  void (*ff)(int,int) = (rand()%2 ? f1 : f2); // если мы захотим вызывать с 2 аргументами
К>  std::function<void(int)> f = std::bind(ff, _1, 7); // если захотим вызывать с 1 аргументом
К>  // если ff не нужен сам по себе - просто подставим его внутрь bind
К>


Если по такому пути идти, то можно и overload_set
Автор: alexeiz
Дата: 05.11.12
прикрутить,
например:
void f(int a,int b)
{
   cout << a << " " << b << endl;
}
int main()
{
   auto defaults = overload( []{f(1,2);}, bind(&f,_1,2) );
   defaults();
   defaults(3);
}

Если нужно ближе к исходной задаче, то что-то типа:
void f(int a,int b,int c)
{
   cout << a << " " << b << " " << c << endl;
}
int main()
{
    auto &&d=defaults(f,11,22,33);
    d();
    d(1);
    d(2,3);
    d(3,4,5);
}
{
    function<void(int,int,int)> general_case{f};
    auto &&d=defaults_n<3>(general_case,11,22,33);
    d();
    d(1);
    d(2,3);
    d(3,4,5);
}

Вывод:
11 22 33
1 22 33
2 3 33
3 4 5
11 22 33
1 22 33
2 3 33
3 4 5

  implementation
#include <type_traits>
#include <functional>
#include <iostream>
#include <ostream>
#include <utility>

using namespace std;

template<bool condition,typename T>
using static_if = typename enable_if<condition,T>::type;

template<typename F> struct func_args;

template<typename Result,typename ...Params>
struct func_args<Result(&)(Params...)>
{
    enum{value=sizeof...(Params)};
};

template<unsigned TotalArgs,typename Func,typename Head,typename ...Tail>
class defaults_set: defaults_set<TotalArgs,Func,Tail...>
{
    typedef defaults_set<TotalArgs,Func,Tail...> parent;
    Head data;
public:
    template<typename F,typename Arg,typename ...Args>
    defaults_set(F &&f,Arg &&arg,Args&&... args)
        : parent{forward<F>(f),forward<Args>(args)...}, data{forward<Arg>(arg)}
    {}
    template<typename ...Args>
    auto operator()(Args&&... args) ->
        static_if
        <
            sizeof...(Tail)+1+sizeof...(Args) == TotalArgs,
            typename result_of<Func(Args&&...,Head,Tail...)>::type
        >
    {
        return parent::operator()(forward<Args>(args)...,data);
    }
    using parent::operator();
};

template<unsigned TotalArgs,typename Func,typename Head>
class defaults_set<TotalArgs,Func,Head>
{
    typename conditional
    <
        is_function< typename remove_reference<Func>::type >::value,
        Func,
        typename remove_reference<Func>::type
    >::type  func;
    Head data;
public:
    template<typename F,typename Arg,typename ...Args>
    defaults_set(F &&f,Arg &&arg)
        : func{forward<F>(f)}, data{forward<Arg>(arg)}
    {}
    template<typename ...Args>
    auto operator()(Args&&... args) ->
        static_if
        <
            1+sizeof...(Args) == TotalArgs,
            decltype(func(forward<Args>(args)...,data))
        >
    {
        return func(forward<Args>(args)...,data);
    }
    template<typename ...Args>
    auto operator()(Args&&... args) ->
        static_if
        <
            sizeof...(Args) == TotalArgs,
            decltype(func(forward<Args>(args)...))
        >
    {
        return func(forward<Args>(args)...);
    }
};

template<typename Func,typename ...Args>
defaults_set<func_args<Func>::value,Func,Args...>  defaults(Func &&f,Args&&... args)
{
    return {forward<Func>(f),forward<Args>(args)...};
}

template<unsigned TotalArgs,typename Func,typename ...Args>
defaults_set<TotalArgs,Func,Args...> defaults_n(Func &&f,Args&&... args)
{
    return {forward<Func>(f),forward<Args>(args)...};
}

// _________________________________________________ //

void f(int a,int b,int c)
{
   cout << a << " " << b << " " << c << endl;
}

int main()
{
    {
        auto &&d=defaults(f,11,22,33);
        d();
        d(1);
        d(2,3);
        d(3,4,5);
    }
    {
        function<void(int,int,int)> general_case{f};
        auto &&d=defaults_n<3>(general_case,11,22,33);
        d();
        d(1);
        d(2,3);
        d(3,4,5);
    }
}

 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.