LINUX.ORG.RU

lambda vs std::function<...>

 


0

4
#include <iostream>
#include <typeinfo>
#include <functional>

struct A { int t; };

template<typename T>
bool f(const T& a, const T& b, std::function<bool(const T&, const T&)> cmp) {
	return cmp(a, b);
}

int main() {
	std::function<bool(const A&, const A&)> cmp = [] (const A& a, const A& b) -> bool {
			return a.t == b.t;
		};
	auto cmp1 = [] (const A& a, const A& b) -> bool {
			return a.t == b.t;
		};
	std::cout << typeid(cmp).name() << "\n";
	std::cout << typeid(cmp1).name() << "\n";
	f(A(), A(), cmp);
	f(A(), A(), cmp1); // lambda.cpp(23) : error C2784: 'bool f(const T &,const T &,std::function<bool(const T &,const T &)>)' : could not deduce template argument for 'std::function<bool(const T &,const T &)>' from 'main::<lambda_7d1f31daea416f31c63c1f4dba55084d>' lambda.cpp(9) : see declaration of 'f'
}

Собственно, что хотелось сказать. Абыдна. Ну и чтоб уже что-то спросить: ткните пальцем в стандарт про это и будет ли в c++14 работать? :) Ну или может я что-то не так делаю?

★★★★★

Последнее исправление: invy (всего исправлений: 1)

bool f(const T& a, const T& b, const std::function<bool(const T&, const T&)> &cmp) {

nanoolinux ★★★★
()

ПРОСТО ТЫ НЕ ОСИЛИЛ.

C++ way

#include <iostream>
#include <typeinfo>
#include <type_traits>
#include <functional>

struct A { int t; };

template<typename T, typename F>
bool f(const T& a, const T& b, F cmp) {
	static_assert(std::is_same<std::function<bool(const T&, const T&)>,
	              decltype(static_cast<std::function<bool(const T&, const T&)>>(cmp))>::value, " ds");
	return cmp(a, b);
}

int main() {
	std::function<bool(const A&, const A&)> cmp = [] (const A& a, const A& b) -> bool {
			return a.t == b.t;
		};
	auto cmp1 = [] (const A& a, const A& b) -> bool {
			return a.t == b.t;
		};
	auto cmp2 = [] (const int& a, const A& b) -> bool {
			return a == b.t;
		};
	std::cout << typeid(cmp).name() << "\n";
	std::cout << typeid(cmp1).name() << "\n";
	f(A(), A(), cmp);
	f(A(), A(), cmp1); 
	f(A(), A(), cmp2); // не работает, как и положено
}

Kuzy ★★★
()

так компилируется

f<A>(A(), A(), cmp1);
anatoly
()
template<typename T>
bool f(const T& a, const T& b, auto cmp) {
	return cmp(a, b);
}

-std=c++1y
Стандарта под рукой нету.

Shadow1251
()
Ответ на: комментарий от Kuzy

template<typename T, typename F>
bool f(const T& a, const T& b, F cmp) {

твою ж так, а... спать надо больше...

invy ★★★★★
() автор топика

Ну собственно, наверное, всем спасибо :)
Хотя, конечно не совсем ясно, почему cmp и cmp1 должны иметь разные типы.

invy ★★★★★
() автор топика
Ответ на: комментарий от invy

Каждая лямбда - отдельный тип. У std::function есть не-explicit конструктор, который принимает лямбду. Темплейты из параметров не-explicit конструкторов не выводятся.

То же самое, без всяких лямбд:

template <typename T>
struct A {
	T value;
	A(int value) : value(value) {}
};

void foo1(A<int> t) {
}

template <typename T>
void foo2(A<T> t) {
}

int main() {
	foo1(5); // компилируется
	foo2(5); // не компилируется
	foo2<int>(5); // компилируется
	
	return 0;
}

Kuzy ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.