Всем привет,
Есть ли трюк подобный этому:
auto ptr = +[](){}; //ptr is of type void (*)()
Но чтобы компилировалось в MSVC2013.
Там оно ругается на ambiguity, потому что MSVC предоставляет 4ре перегрузки, под каждый calling convention.
Может темплейтик какой написать, который мог бы принимать captureless лямбду и конвертировать её в указатель.
auto ptr = (ToPointer)[](){};
Здравствуйте, johny5, Вы писали:
J>Есть ли трюк подобный этому:
J>J>auto ptr = +[](){}; //ptr is of type void (*)()
J>
J>Может темплейтик какой написать, который мог бы принимать captureless лямбду и конвертировать её в указатель.
J>J>auto ptr = (ToPointer)[](){};
J>
Держите вот такой несложный трюк (компилируется на
clang 3.6.0 и
g++ 5.1.0 с
-std=c++11 -Wall -Wextra -Werror -pedantic-errors и на
Visual Studio 2015 RC, на
Visual Studio 2013 RTM не компилируется, может быть повезет с более новыми версиями
Visual Studio 2013 Update X):
#include <type_traits>
template <typename Type>
struct RemoveQualifier_
{
using type = Type;
};
template <typename ReturnType, typename... Arguments>
struct RemoveQualifier_<ReturnType(Arguments...)const>
{
using type = ReturnType(Arguments...);
};
template <typename Function>
using RemoveQualifier = typename RemoveQualifier_<Function>::type;
template <class C, typename F>
RemoveQualifier<F>* ExtractFunction(F C::*);
template <typename Lambda>
auto ToFunctionPointer(Lambda&& lambda) -> decltype(ExtractFunction(&Lambda::operator()))
{
return lambda;
}
Использовать можно так:
auto function1 = ToFunctionPointer([](){ std::cout << "Usual lambda without a capture list." << std::endl; });
auto function2 = ToFunctionPointer([](int i) mutable { std::cout << "Mutable lambda without a capture list. Parameter value: " << i << std::endl; });
function1();
function2(42);
Т.е. можно работать даже с мутабельными лямбдами (хотя без списка захвата они тождественны обычным, но их оператор
operator() все же не имеет квалификатора
const, поэтому нужно реализовывать общий вариант шаблона
RemoveQualifier_, иначе можно было бы просто написать
template <typename> struct RemoveQualifier_;).
Здравствуйте, Constructor, Вы писали:
Поигрался с вашим примером.
Вот такое заработало на MSVC2013:
auto lambda = [](int a){ std::cout << "Usual lambda without a capture list." << std::endl; };
function_traits< decltype(&decltype(lambda)::operator()) >::function_type* f = lambda;
f(5);
function_traits отсюда:
https://functionalcpp.wordpress.com/2013/08/05/function-traits/
Я только добавил
typedef R (function_type)( Args... ) ;
(почему то не получилось написать через using function_type = R (Args ...);
Осталось спрятать это всё под капот конвертера ToFunctionPointer.
Спасибо за помощь.