Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::函数中参数的自动动态_强制转换_C++ - Fatal编程技术网

C++ std::函数中参数的自动动态_强制转换

C++ std::函数中参数的自动动态_强制转换,c++,C++,我们有多态类A和B,如: struct A { virtual ~A() {} }; struct B final : public A { void f() { std::cout << "f" << std::endl; } }; 有没有什么方法可以在不使用[](A*A){}包装内部函数的情况下自动实现这一点?我的目标是使以下语法正常工作: std::function<void(A*)> funcA = dynStdFunc([](B*

我们有多态类A和B,如:

struct A {
    virtual ~A() {}
};
struct B final : public A {
    void f() { std::cout << "f" << std::endl; }
};

有没有什么方法可以在不使用
[](A*A){}
包装内部函数的情况下自动实现这一点?

我的目标是使以下语法正常工作:

std::function<void(A*)> funcA = dynStdFunc([](B* b) { b->f(); });
它接受functionoid类型,并返回一个包含其参数类型的
pack
。太好了


2.std::function所需的参数在
dynStdFunc
内部是未知的。我们实现这一点的方法是返回一个临时对象,其中包含一个模板,用于将运算符转换为
std::function


.

为了清楚起见,
{b->f();}
是使用
b
的整个函数体的占位符,对吗?@Quentin对。这似乎是一个非常做作的示例。你能详细说明一下你想用这个解决方案解决的实际问题吗?
f()
不应该是虚拟的,这样你就可以从
A
实例中调用它了吗?在那种情况下,没有铸造。我可以解决这个问题,但我不想。因为您可能会使用我的解决方案将允许同时使用动态强制转换指针和非强制转换参数。还允许外包装是
[](自动&&…->decltype(自动)
,而不是在
std::function
@Yakk的类型上进行匹配。a
std::function
可以调用泛型functor吗?@Yakk oooh。这是一个戈德堡级的滥杀滥伤。
std::function<void(A*)> funcA = dynStdFunc([](B* b) { b->f(); });
// C++17's void_t
template <class...>
using void_t = void;

// Pack of arbitrary types
template <class...>
struct pack { };

namespace detail_parameters {
    template <class F, class = void_t<>>
    struct parameters { };

    template <class F>
    struct parameters<F, void_t<decltype(&F::operator ())>>
    : parameters<decltype(&F::operator ())> { };

    template <class R, class... Params>
    struct parameters<R(Params...)> { using type = pack<Params...>; };

    // More specializations for functions, function pointers,
    // member function pointers...
}

// Retrieve the parameter list from a functionoid
template <class F>
using parameters = typename detail_parameters::parameters<std::remove_reference_t<F>>::type;
namespace detail_dynStdFunc {

    // F = functionoid, Ps = pack of its parameters
    template <class F, class Ps>
    struct wrapper;

    template <class F, class... Ps>
    struct wrapper<F, pack<Ps...>> {

        template <class Ret, class... Args>
        operator std::function<Ret(Args...)> () {
            // Now we know what parameters the `std::function` needs
        }

        F f;
    };
}

template <class F>
auto dynStdFunc(F &&f) {
    return detail_dynStdFunc::wrapper<
        std::remove_reference_t<F>,
        parameters<F>
    >{std::forward<F>(f)};
}
template <class Ret, class... Args>
operator std::function<Ret(Args...)> () {
    return [f_ = std::move(f)](Args... args) -> Ret {
        return f_(dynamic_cast<Ps>(args)...);
    };
}
template <class F, class... Ps>
auto dynStdFunc(F &&f, pack<Ps...>) {
    return [f_ = std::forward<F>(f)](auto *... args) -> decltype(auto) {
        return f_(dynamic_cast<Ps>(args)...);
    };
}

template <class F>
auto dynStdFunc(F &&f) {
    return dynStdFunc(std::forward<F>(f), parameters<F>{});
}