У меня была эта разочаровывающая ошибка в среде разработки в Visual studio, и выяснилось, что причина была совсем немой. Короче, если у вас есть несколько веб-проектов / сайтов в решении: убедитесь, что порт, к которому вы пытаетесь получить доступ к веб-сайту, тот же, что и в Project Properties-> Web
. В моем случае, ошибка была вызвана тем, что я использовал другой порт для доступа к веб-сайту (в браузере), а проекту в решении был назначен другой порт. Чтобы объяснить немного больше, у меня было два проекта веб-сайта в моем решении Website1 (назначенный порт 8001 в ISS от Visual-Studio) и Website2 (назначенный порт 8101 в ISS Visual-Studio). Так что, даже если я создавал Website1, я пытался получить доступ к веб-сайту с помощью locahost: 8101.
Теперь, когда я, наконец, понял проблему, я вижу, что комментарий @ StingyJack касается аналогичной проблемы.
Вы можете использовать вывод аргумента класса шаблона с 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*/>;
Если
blockquote>decltype(&F::operator())
имеет формуR(G::*)(A...)
(опциональноcv
-качественно , опциональноnoexcept
, опционально lvalue ссылка квалифицирована) для некоторого типа классаG
, тогда выводимый тип -std::function<R(A...)>
. Эта перегрузка участвует только в разрешении перегрузки, если&F::operator()
правильно сформирован, когда рассматривается как неоцененный операнд.
Я нашел один метод, который использует подклассы специализации (см. здесь ):
/* 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;
}
Вы можете пройти через какую-то хитрость, например:
#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;
}