Re[9]: std::function, could not deduce template argument
От: PM  
Дата: 15.02.15 12:19
Оценка: 44 (1)
Здравствуйте, c-smile, Вы писали:

PM>>Еще по теме, а обязательно нужно стирание типов с std::function? Может быть удастся обойтись шаблонной f()


[здесь было объяснение]

А, это видимо реализация xcall в Sciter. Тогда да, тут нужно стирание типов. Как уже написал выше Булат, std::function и лямбды имеют разный тип. Так что нужно нечто, преобразующее лямбду в std::function, и без поддержки variadic templates придется писать набор перегруженных функций для разумного кол-ва аргументов, тут без вариантов.

Идея в том, чтобы в function_traits для лямбды хранить тип соответствующей std::function. Вот специализации function_traits для лямбд с 0..2 аргументами:

template<typename Function>
struct function_traits : public function_traits<decltype(&Function::operator())>
{
};

// []() -> R
template<typename Lambda, typename R>
struct function_traits<R(Lambda::*)() const>
{
    typedef std::function<R()> function;
};

// []() mutable -> R
template<typename Lambda, typename R>
struct function_traits<R(Lambda::*)()>
{
    typedef std::function<R()> function;
};

// [](P0) -> R
template<typename Lambda, typename R, typename P0>
struct function_traits<R(Lambda::*)(P0) const>
{
    typedef std::function<R(P0)> function;
};

// [](P0) mutable -> R
template<typename Lambda, typename R, typename P0>
struct function_traits<R(Lambda::*)(P0)>
{
    typedef std::function<R(P0)> function;
};

// [](P0, P1) -> R
template<typename Lambda, typename R, typename P0, typename P1>
struct function_traits<R(Lambda::*)(P0, P1) const>
{
    typedef std::function<R(P0, P1)> function;
};

// [](P0, P1) mutable -> R
template<typename Lambda, typename R, typename P0, typename P1>
struct function_traits<R(Lambda::*)(P0, P1)>
{
    typedef std::function<R(P0, P1)> function;
};

template <typename Function>
struct function_traits<Function&> :function_traits<Function>{};

template <typename Function>
struct function_traits<Function&&> :function_traits<Function>{};

template<typename Lambda> //TODO: enable_if Lambda::operator() ?
value vfunc(Lambda&& lambda)
{
    typedef typename function_traits<Lambda>::function function;
    return vfunc(static_cast<function>(lambda));
}


Полный код: http://coliru.stacked-crooked.com/a/861aea7b8ee370fb

Идея найдена здесь: http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html, вот еще тема на StackOverflow: http://stackoverflow.com/questions/13358672/how-to-convert-a-lambda-to-an-stdfunction-using-templates
Re: std::function, could not deduce template argument
От: BulatZiganshin  
Дата: 15.02.15 15:58
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Есть вот такая конструкция


вот так заработало с gcc49, но не msvc2013:

  Скрытый текст
#include <functional>
#include <iostream>

template <typename T>
void f(std::function<void(T)> g)
{
    std::cout << "1 arg:";
    g(-1);
}

template <typename T>
void f(void g(T))
{
    std::cout << "1 arg:";
    g(1);
}

template <typename T1, typename T2>
void f(void g(T1,T2))
{
    std::cout << "2 args:";
    g(11,22);
}

template <typename T1, typename T2, typename T3>
void f(void g(T1,T2,T3))
{
    std::cout << "3 args:";
    g(111,222,333);
}

int main(int argc, char* argv[])
{
    auto func1 = [](int x) { std::cout << x << std::endl; };
    auto func2 = [](int x, int y) { std::cout << x << y << std::endl; };
    auto func3 = [](int x, int y, int z) { std::cout << x << y << z << std::endl; };

    f(+func1);
    f(+func2);
    f(+func3);

    return 0;
}

ключевые моменты — "+func1" и "void f(void g(T1,T2))" в дополнение к перегрузке по std::function. сообщение msvc об ошибке тоже достойно увековечения:
lambda_as_std_function2.cpp(27) : error C2593: 'operator +' is ambiguous
        could be 'built-in C++ operator+(void (__cdecl *)(int))'
        or       'built-in C++ operator+(void (__vectorcall *)(int))'
        while trying to match the argument list '(main::<lambda_c762786ee855352b046bdd0fba86f419>)'


по большому счёту, я знаю библиотеки которые принимают шаблонные лямбды на входе (включая std), значит решение есть. вот что я вижу в одной из них:

  Скрытый текст
использование:
    /**
     * Same as the other writeFunction, except that the template parameter is automatically detected
     * This only works if the data is either a native function pointer, or contains one operator() (this is the case for lambdas)
     */
    template<typename... TData>
    void writeFunction(TData&&... data) noexcept {
        static_assert(sizeof...(TData) >= 2, "You must pass at least a variable name and a value to writeFunction");
        typedef typename std::decay<typename std::tuple_element<sizeof...(TData) - 1,std::tuple<TData...>>::type>::type
            RealDataType;
        typedef typename FunctionTypeDetector<RealDataType>::type
            DetectedFunctionType;
        
        return writeFunction<DetectedFunctionType>(std::forward<TData>(data)...);
    }

определение:
    // this structure takes a pointer to a member function type and returns the base function type
    template<typename TType>
    struct RemoveMemberPointerFunction { typedef void type; };          // required because of a compiler bug

    // this structure takes any object and detects its function type
    template<typename TObjectType>
    struct FunctionTypeDetector { typedef typename RemoveMemberPointerFunction<decltype(&std::decay<TObjectType>::type::operator())>::type type; };


// this structure takes any object and detects its function type
template<typename TRetValue, typename... TParameters>
struct LuaContext::FunctionTypeDetector<TRetValue (TParameters...)>             { typedef TRetValue type(TParameters...); };
template<typename TObjectType>
struct LuaContext::FunctionTypeDetector<TObjectType*>                           { typedef typename FunctionTypeDetector<TObjectType>::type type; };

// this structure takes a pointer to a member function type and returns the base function type
template<typename TType, typename TRetValue, typename... TParameters>
struct LuaContext::RemoveMemberPointerFunction<TRetValue (TType::*)(TParameters...)>                    { typedef TRetValue type(TParameters...); };
template<typename TType, typename TRetValue, typename... TParameters>
struct LuaContext::RemoveMemberPointerFunction<TRetValue (TType::*)(TParameters...) const>              { typedef TRetValue type(TParameters...); };
template<typename TType, typename TRetValue, typename... TParameters>
struct LuaContext::RemoveMemberPointerFunction<TRetValue (TType::*)(TParameters...) volatile>           { typedef TRetValue type(TParameters...); };
template<typename TType, typename TRetValue, typename... TParameters>
struct LuaContext::RemoveMemberPointerFunction<TRetValue (TType::*)(TParameters...) const volatile>     { typedef TRetValue type(TParameters...); };
Люди, я люблю вас! Будьте бдительны!!!
Re[3]: std::function, could not deduce template argument
От: c-smile Канада http://terrainformatica.com
Дата: 15.02.15 18:13
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Константин, Вы писали:


К>>Здравствуйте, c-smile, Вы писали:


К>>Какая-то пессимизация на пустом месте. Вместо функторов которые ещё и отлично инлайнятся, всё гонится через тяжёлый std::function. Зачем???


J>У c-smile там фреймворк с колбеками, так что, я думаю, это для хранения оных, и в этом смысле std::function подходит лучше всего.


Это для передачи native functions в script. Можно считать что это callbacks в каком-то роде.
Решение, кстати, для любого script integration может быть полезно.

Скажем в script (JavaScript, TIScript) я могу написать такое:

function getRecordset( params ) {
   var nrs = ...; // opening  recordset somehow
   function nextRecord() { gets next record from nrs }
   function prevRecord() { gets prev record from nrs }
   
   // returns public API of the recordset, hides nrs completely: 
   return {
     next: nextRecord, 
     prev: prevRecord
     ...
   };
}


И использование

var rs = getRecordset("shoppingCartData");

while(var record = rs.next()) {
  ...
}


getRecordset может быть native (С++) функция

value getRecordset() {
  std::shared_ptr<db::recordset> nrs = ....

  std::function<value()> nextRecord = [nrs]() -> value {
    ... return next record as key/value map
    ... or 'undefined' as value() 
  };
  std::function<value()> prevRecord = [nrs]() -> value { ...  };

  value r; 
  r.set_item("next", vfunc(nextRecord) );
  r.set_item("prev", vfunc(prevRecord) );
  return r;
}


Это вот выше уже и так работает. Просто хотелось еще и auto разрешить.

Вот интересно, C++ компилятор же как-то проверяет типы слева и справа здесь:
 std::function<...> var = ...lambda...;


т.е. им можно, а нам не нельзя ?
Re[4]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 00:28
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Вот интересно, C++ компилятор же как-то проверяет типы слева и справа здесь:

CS>
CS> std::function<...> var = ...lambda...;
CS>


CS>т.е. им можно, а нам не нельзя ?


Ну он же тут проверяет конкретные указанные тобой типы аргументов, а не выводит их.

В этом смысле достаточно SFINAE в конструкторе по decltype(lambda(int(),int())) — в смысле, проверить, что для этих типов код компилируется (заодно и шаблонные автолямбды так же накрываются — а у них ведь тип аргумента в принципе невозможно вывести).

(Правда, не уверен, что это именно так работает в вц2010, да и знать не хочу, если честно, я не палеонтолог в душе Вполне возможно, что они у себя тупо недокументированным интерфейсом пользуются)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: std::function, could not deduce template argument
От: c-smile Канада http://terrainformatica.com
Дата: 16.02.15 01:10
Оценка:
Здравствуйте, jazzer, Вы писали:

J>В этом смысле достаточно SFINAE в конструкторе по decltype(lambda(int(),int())) — в смысле, проверить, что для этих типов код компилируется (заодно и шаблонные автолямбды так же накрываются — а у них ведь тип аргумента в принципе невозможно вывести).


Если lambda это некий уникальный тип то почему бы не сделать

decltype(lambda [](int,int)->int) -> std::function<int(int,int)>


ну или хотя бы

auto foo = [](int a,int b) { return a + b; };

decltype(foo)::function_type -> std::function<int(int,int)>


Компайлер ведь этой всей информацией обладает...
Re[6]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 02:57
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Здравствуйте, jazzer, Вы писали:


J>>В этом смысле достаточно SFINAE в конструкторе по decltype(lambda(int(),int())) — в смысле, проверить, что для этих типов код компилируется (заодно и шаблонные автолямбды так же накрываются — а у них ведь тип аргумента в принципе невозможно вывести).


CS>Если lambda это некий уникальный тип то почему бы не сделать


CS>
CS>decltype(lambda [](int,int)->int) -> std::function<int(int,int)> 
CS>


CS>ну или хотя бы


CS>
CS>auto foo = [](int a,int b) { return a + b; };

CS>decltype(foo)::function_type -> std::function<int(int,int)> 
CS>


CS>Компайлер ведь этой всей информацией обладает...


это возможно только в самом тривиальном случае.
как насчет вот этого?
  auto a = [](auto x){ cout << x << endl; };
  a(1);
  a(3.14);
  a("asd");
  
  std::function<void(int)> fi{a}; 
  std::function<void(double)> fd{a}; 
  std::function<void(const char*)> fs{a}; 

  fi(1);
  fd(3.14);
  fs("asd");

Какой function_type должен быть у а?

как насчет вот этого?
  auto b = [](double x){ cout << x << endl; };
  std::function<void(int)> fb{b};
  fb(3.14); // напечатает 3
  
  auto c = [](int x){ cout << x << endl; };
  std::function<void(double)> fc{c};
  fc(3.14); // тоже напечатает 3


ты можешь спросить компилятор: "Можно ли привести лямбду к std::function конкретного типа?", но не спросить: "А дай мне все std::function, которые можно инициализировать из этой лямбды".
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[7]: std::function, could not deduce template argument
От: c-smile Канада http://terrainformatica.com
Дата: 16.02.15 03:43
Оценка:
Здравствуйте, jazzer, Вы писали:

CS>>
CS>>auto foo = [](int a,int b) { return a + b; };

CS>>decltype(foo)::function_type -> std::function<int(int,int)> 
CS>>


CS>>Компайлер ведь этой всей информацией обладает...


J>это возможно только в самом тривиальном случае.

J>как насчет вот этого?
J>
J>  auto a = [](auto x){ cout << x << endl; };
J>  a(1);
J>  a(3.14);
J>  a("asd");
  
J>  std::function<void(int)> fi{a}; 
J>  std::function<void(double)> fd{a}; 
J>  std::function<void(const char*)> fs{a}; 

J>  fi(1);
J>  fd(3.14);
J>  fs("asd");
J>

J>Какой function_type должен быть у а?

Это вот
auto a = [](auto x){ cout << x << endl; };


вообще-то не должно компилироваться вообще так как есть фактически это вот

template <typename X> lambda_type [](X x){ cout << x << endl; };

lambda_type<int> a; 
a(1);

lambda_type<double> a; 
a(3.14);

lambda_type<const char*> a; 
a("asd");


Но это смысла не имеет так как у тебя три переменные с одним именем.

Или я чего-то не понял концептуально?

J>как насчет вот этого?

J>
J>  auto b = [](double x){ cout << x << endl; };
J>  std::function<void(int)> fb{b};
J>  fb(3.14); // напечатает 3
  
J>  auto c = [](int x){ cout << x << endl; };
J>  std::function<void(double)> fc{c};
J>  fc(3.14); // тоже напечатает 3
J>


Это вообще мрак если честно. Я не понимаю зачем оно так сделано. Зачем эти дурацкие касты?
Re[8]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 04:09
Оценка: 23 (2) +1
Здравствуйте, c-smile, Вы писали:

CS>Это вот

CS>
CS>auto a = [](auto x){ cout << x << endl; }; 
CS>


CS>вообще-то не должно компилироваться вообще так как есть фактически это вот


CS>
CS>template <typename X> lambda_type [](X x){ cout << x << endl; };

CS>lambda_type<int> a; 
CS>a(1);

CS>lambda_type<double> a; 
CS>a(3.14);

CS>lambda_type<const char*> a; 
CS>a("asd");
CS>


CS>Но это смысла не имеет так как у тебя три переменные с одним именем.


CS>Или я чего-то не понял концептуально?


ага. у тебя template<class X> не там, он должен быть внутри, а не снаружи. Эквивалентный функциональный объект выглядит как-то так:
// template<class X> -- не здесь!
struct PrintX
{
  template<class X> // вот он где!
  void operator()(X x) { cout << x << endl; }; 
};

Если бы он был снаружи — твои соображения были бы верны.

ЗЫ Именно так работала и Boost.Lambda. Ты мог одно и то же имя (как а выше) вызывать с разными аргументами.
Добро пожаловать в С++14! (если ты пропустил вечеринку с Boost.Lambda)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: std::function, could not deduce template argument
От: c-smile Канада http://terrainformatica.com
Дата: 16.02.15 05:30
Оценка:
Здравствуйте, jazzer, Вы писали:


CS>>Или я чего-то не понял концептуально?


J>ага. у тебя template<class X> не там, он должен быть внутри, а не снаружи. Эквивалентный функциональный объект выглядит как-то так:

J>
J>// template<class X> -- не здесь!
J>struct PrintX
J>{
J>  template<class X> // вот он где!
J>  void operator()(X x) { cout << x << endl; }; 
J>};
J>

J>Если бы он был снаружи — твои соображения были бы верны.

Зашибись, но как это работает в случае capturing lambda:

void test() {
  intptr_t counter = 0;
  auto lambda = [&counter](auto x) { counter += x; return counter; };
  lambda(5);
  lambda(5.5);
  lambda("hello");
}


?

J>ЗЫ Именно так работала и Boost.Lambda. Ты мог одно и то же имя (как а выше) вызывать с разными аргументами.

J>Добро пожаловать в С++14! (если ты пропустил вечеринку с Boost.Lambda)

С++14 ... Тут за счастье полную поддержку С++11 поиметь хотя бы.
Добро пожаловать в мир practical programming
Re[10]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 06:02
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Зашибись, но как это работает в случае capturing lambda:


CS>
CS>void test() {
CS>  intptr_t counter = 0;
CS>  auto lambda = [&counter](auto x) { counter += x; return counter; };
CS>  lambda(5);
CS>  lambda(5.5);
CS>  lambda("hello");
CS>}
CS>


Точно так же:
struct Lambda
{
  intptr_t& counter;

  template<class X>
  intptr_t operator()(X x) { counter += x; return counter; }; 
};

Естественно, строчка lambda("hello"); не скомпилируется.

CS>С++14 ... Тут за счастье полную поддержку С++11 поиметь хотя бы.

CS>Добро пожаловать в мир practical programming

Да я тоже на С++98 на работе сижу, все никак не переедем
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[5]: std::function, could not deduce template argument
От: BulatZiganshin  
Дата: 16.02.15 07:03
Оценка:
Здравствуйте, jazzer, Вы писали:

CS>> std::function<...> var = ...lambda...;


J>Ну он же тут проверяет конкретные указанные тобой типы аргументов, а не выводит их.


насколько я понимаю, тут срабатывает шаблонный конструктор, так что задача ровно та же самая
Люди, я люблю вас! Будьте бдительны!!!
Re[6]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 07:08
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>Здравствуйте, jazzer, Вы писали:

CS>>> std::function<...> var = ...lambda...;
J>>Ну он же тут проверяет конкретные указанные тобой типы аргументов, а не выводит их.

BZ>насколько я понимаю, тут срабатывает шаблонный конструктор, так что задача ровно та же самая


Нет, не та же.
В std::function<void(int)> var = []{} ты просишь компилятор проверить, можно ли использовать int (который ты своими руками написал).
А исходная задача — вывести этот int.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[11]: std::function, could not deduce template argument
От: PM  
Дата: 16.02.15 08:28
Оценка:
Здравствуйте, jazzer, Вы писали:

CS>>
CS>>void test() {
CS>>  intptr_t counter = 0;
CS>>  auto lambda = [&counter](auto x) { counter += x; return counter; };
CS>>  lambda(5);
CS>>  lambda(5.5);
CS>>  lambda("hello");
CS>>}
CS>>


J>Точно так же:

J>
J>struct Lambda
J>{
J>  intptr_t& counter;

J>  template<class X>
J>  intptr_t operator()(X x) { counter += x; return counter; }; 
J>};
J>

J>Естественно, строчка lambda("hello"); не скомпилируется.

Я думал это будет operator()(X) const, а неконстантная версия используется с mutable lambda

auto lambda1 = [](int x) mutable { return x; }
auto lambda2 = [](int x) { return x; }

// сгенерированный компилятором эквивалент
struct generated_lambda1
{
    int operator()(int x) const { return x; }
}

struct generated_lambda2
{
    int operator()(int x) { return x; }
}
Re[12]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 08:32
Оценка:
Здравствуйте, PM, Вы писали:

PM>Я думал это будет operator()(X) const, а неконстантная версия используется с mutable lambda


Да, конечно, просто в случае захвата по ссылке это рояли не играет.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: std::function, could not deduce template argument
От: Evgeny.Panasyuk Россия  
Дата: 16.02.15 09:24
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>
CS>   // 
CS>   template<typename R,typename P0>
CS>      inline value vfunc( std::function<R(P0)> func )
CS>      {
CS>        return value([func](unsigned int argc, const value* argv) -> value { 
CS>          R r = func(argc >= 1? argv[0].get<P0>(): P0() ); 
CS>          return value(r); }); 
CS>      }
CS>


Здесь получается лишняя std::function, а достаточно одной, которая в value.
Re[6]: std::function, could not deduce template argument
От: Evgeny.Panasyuk Россия  
Дата: 16.02.15 09:25
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>Если lambda это некий уникальный тип то почему бы не сделать


CS>
CS>decltype(lambda [](int,int)->int) -> std::function<int(int,int)> 
CS>


CS>ну или хотя бы


CS>
CS>auto foo = [](int a,int b) { return a + b; };

CS>decltype(foo)::function_type -> std::function<int(int,int)> 
CS>


CS>Компайлер ведь этой всей информацией обладает...



Такую метафункцию (принимающую тип лямбды и возвращающую соответствующий тип std::function) можно сделать вручную — как уже показали выше через decltype
Автор: uzhas
Дата: 11.05.13
(+ эмуляция variadic'ов на MSVC2010).
Но, как уже заметили, есть ограничение — это полиморфные лямбды (которых нет в MSVC2010) и функциональные объекты с шаблонным либо перегруженным operator().
Re[7]: std::function, could not deduce template argument
От: BulatZiganshin  
Дата: 16.02.15 10:11
Оценка:
Здравствуйте, jazzer, Вы писали:

J>В std::function<void(int)> var = []{} ты просишь компилятор проверить, можно ли использовать int (который ты своими руками написал).

J>А исходная задача — вывести этот int.

это если std::function встроен в компилятор. я предполагаю, что он написан в обычном заголовочном файле и эта строка обрабатывается шаблонным конструктором. иными словами, напиши эквивалентный std::function тип, чтобы он такое принимал
Люди, я люблю вас! Будьте бдительны!!!
Re[8]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 10:35
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>Здравствуйте, jazzer, Вы писали:


J>>В std::function<void(int)> var = []{} ты просишь компилятор проверить, можно ли использовать int (который ты своими руками написал).

J>>А исходная задача — вывести этот int.

BZ>это если std::function встроен в компилятор. я предполагаю, что он написан в обычном заголовочном файле и эта строка обрабатывается шаблонным конструктором. иными словами, напиши эквивалентный std::function тип, чтобы он такое принимал


про то, как это может быть в конструкторе, я уже писал тут
Автор: jazzer
Дата: 16.02.15
.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[9]: std::function, could not deduce template argument
От: BulatZiganshin  
Дата: 16.02.15 10:41
Оценка:
Здравствуйте, jazzer, Вы писали:

J>>>В std::function<void(int)> var = []{} ты просишь компилятор проверить, можно ли использовать int (который ты своими руками написал).

J>>>А исходная задача — вывести этот int.

J>про то, как это может быть в конструкторе, я уже писал тут
Автор: jazzer
Дата: 16.02.15
.


я не вижу здесь никакой разницы с шаблонным вызовом функции. ты не мог бы привести этот конструктор?
Люди, я люблю вас! Будьте бдительны!!!
Re[10]: std::function, could not deduce template argument
От: jazzer Россия Skype: enerjazzer
Дата: 16.02.15 10:55
Оценка: 18 (1)
Здравствуйте, BulatZiganshin, Вы писали:

BZ>Здравствуйте, jazzer, Вы писали:


J>>>>В std::function<void(int)> var = []{} ты просишь компилятор проверить, можно ли использовать int (который ты своими руками написал).

J>>>>А исходная задача — вывести этот int.

J>>про то, как это может быть в конструкторе, я уже писал тут
Автор: jazzer
Дата: 16.02.15
.


BZ>я не вижу здесь никакой разницы с шаблонным вызовом функции. ты не мог бы привести этот конструктор?


ну типа так (пишу в браузере):
template<class F> // F - это void(int)
struct function
{
  F f;
  using argT = traits<F>....;  // int

                               //       объект-лямбда   объект-аргумент типа argT
  template<class L, class = decltype( ( *(L*)nullptr )( *(argT*)nullptr ) )> // SFINAE
  function(L lambda): f{lambda} {}

  //... другие конструкторы
};

этот конструктор скомпилируется, только если вызов lambda с аргументом типа argT валиден.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.