Сигнатура функции лямбда-функции в шаблонном совпадении специализации на c ++ - 17

У меня была эта разочаровывающая ошибка в среде разработки в Visual studio, и выяснилось, что причина была совсем немой. Короче, если у вас есть несколько веб-проектов / сайтов в решении: убедитесь, что порт, к которому вы пытаетесь получить доступ к веб-сайту, тот же, что и в Project Properties-> Web

. В моем случае, ошибка была вызвана тем, что я использовал другой порт для доступа к веб-сайту (в браузере), а проекту в решении был назначен другой порт. Чтобы объяснить немного больше, у меня было два проекта веб-сайта в моем решении Website1 (назначенный порт 8001 в ISS от Visual-Studio) и Website2 (назначенный порт 8101 в ISS Visual-Studio). Так что, даже если я создавал Website1, я пытался получить доступ к веб-сайту с помощью locahost: 8101.

Теперь, когда я, наконец, понял проблему, я вижу, что комментарий @ StingyJack касается аналогичной проблемы.

2
задан Konrad Eisele 15 January 2019 в 16:37
поделиться

3 ответа

Вы можете использовать вывод аргумента класса шаблона с std::function:

template <typename LambdaType, typename=void>                                                                                               
struct split {                                                                                                                              
    using StdFunctionType = decltype(std::function{std::declval<LambdaType>()});                                                                                                                                  
};     

Когда у вас есть std::function, соответствующее вашей лямбде, вы можете извлечь типы возврата и аргумента, используя специализацию шаблона. [1114 ]

Это работает, потому что std::function имеет руководство по удержанию :

template<class F>
function(F) -> function</*see below*/>;

Если decltype(&F::operator()) имеет форму R(G::*)(A...) (опционально cv -качественно , опционально noexcept, опционально lvalue ссылка квалифицирована) для некоторого типа класса G, тогда выводимый тип - std::function<R(A...)>. Эта перегрузка участвует только в разрешении перегрузки, если &F::operator() правильно сформирован, когда рассматривается как неоцененный операнд.

0
ответ дан Holt 15 January 2019 в 16:37
поделиться

Я нашел один метод, который использует подклассы специализации (см. здесь ):

/* g++ -std=c++17 */
#include <iostream>
#include <string>
#include <array>
#include <map>
#include <functional>

template<typename T> struct tag {};
struct mybase {};

/* subclass specialization on type of operator() of lambda: */
template<class Ld>
struct split : split<decltype(&Ld::operator())>
{
    split(Ld &&f) : split<decltype(&Ld::operator())>(std::forward<Ld>(f)) {};
};

template <typename RetType, typename... ArgTypes>
struct split<std::function<RetType(ArgTypes...)>>  {
    split(std::function<RetType(ArgTypes...)> &&f) {
        std::cout << "std::function" << std::endl;
    };
};

template <typename RetType, typename... ArgTypes>
struct split<RetType(*)(ArgTypes...)> {
    split(RetType(*f)(ArgTypes...)) {
        std::cout << "func-ptr" << std::endl;
    };
};

template <typename RetType, class Cls, typename... ArgTypes>
struct split<RetType(Cls::*)(ArgTypes...) const >  {
    split(const Cls &&f) {
        std::cout << "[]() const" << std::endl;
    };
};

template <typename RetType, class Cls, typename... ArgTypes>
struct split<RetType(Cls::*)(ArgTypes...) >  {
    split(Cls &&f) {
        std::cout << "[]()" << std::endl;
    };
};


void f1(int) {};

int
main(int argc, char **argv) {

    new split<std::decay<decltype(f1)>::type>(f1);
    new split<std::function<void(int)>>(std::function<void(int)>([](int) {}));

    /* no g++-17: */
    //auto l = [](int){};
    //new split<decltype(l)>(std::forward<decltype(l)>(l));

    /* g++-17: */
    new split([](int){});

    return 0;
}
0
ответ дан Konrad Eisele 15 January 2019 в 16:37
поделиться

Вы можете пройти через какую-то хитрость, например:

#include <type_traits>

template <typename LambdaType, typename=void>                                                                                               
struct split {                                                                                                                              
    split(LambdaType &&f) { deduce(&LambdaType::operator()); }
    template<class RET, class CLOSURE, class... ARGS>
    void deduce(RET(CLOSURE::*)(ARGS...) const) {
       // You have your return and args here
    }
};                                                                                                                                          


template <typename RetType, typename... ArgTypes>                                                                                           
struct split<RetType(*)(ArgTypes...)> {                                                                                                     
    split(RetType(*f)(ArgTypes...));                                                                                                                                      
};                                                                                                                                  

void f1(int) {};                                                                                                                            

int                                                                                                                                         
main(int argc, char **argv) {                                                                                                               

    split<std::decay_t<decltype(f1)>>{f1};                                                                                          

    /* how can I extract the argument type template pack from lambda ? */                                                                   
    split([](int){});                                                                                                                   
    return 0;                                                                                                                               
}   
0
ответ дан SergeyA 15 January 2019 в 16:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: