Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ 采用lambda的模板类的类型推断_C++_Templates_Lambda_C++17 - Fatal编程技术网

C++ 采用lambda的模板类的类型推断

C++ 采用lambda的模板类的类型推断,c++,templates,lambda,c++17,C++,Templates,Lambda,C++17,我正在尝试编写一个类,该类能够在以后调用lambda而无需任何参数。我希望C++17类模板参数推断可以避免使用工厂函数。但是,尝试在不指定类型的情况下实例化对象失败。我可以使用工厂函数,但我想了解为什么会发生这种情况 我使用的是VC++2017,启用了C++17工具集。这是预期的行为吗?为什么?由于模板函数和模板类的类型推断规则不同,工厂函数是否可以避免,或者是否需要工厂函数?任何帮助都会得到报答 template <typename F> class WillInvoke { pu

我正在尝试编写一个类,该类能够在以后调用lambda而无需任何参数。我希望C++17类模板参数推断可以避免使用工厂函数。但是,尝试在不指定类型的情况下实例化对象失败。我可以使用工厂函数,但我想了解为什么会发生这种情况

我使用的是VC++2017,启用了C++17工具集。这是预期的行为吗?为什么?由于模板函数和模板类的类型推断规则不同,工厂函数是否可以避免,或者是否需要工厂函数?任何帮助都会得到报答

template <typename F>
class WillInvoke
{
public:
    WillInvoke(std::decay_t<F> f) : f(std::move(f)) { }

    void CallNow() { f(); }

private:
    std::decay_t<F> f;
};

template <typename F>
WillInvoke<F> make_WillInvoke(F && f)
{
    return WillInvoke<F>(std::forward<F>(f));
}

int main()
{
    // OK
    auto w = make_WillInvoke([](){ std::cout << "Hello World"; });
    w.CallNow();

    // Won't compile
    WillInvoke w2([](){ std::cout << "Hello World"; }); // No instance of constructor matches argument list
    w2.CallNow();
}
模板
威林沃克级
{
公众:
WillInvoke(std::decation\u t f):f(std::move(f)){
void CallNow(){f();}
私人:
标准::衰变_tf;
};
模板
WillInvoke make_WillInvoke(F&F)
{
返回WillInvoke(std::forward(f));
}
int main()
{
//嗯

auto w=make_WillInvoke([])(){std::cout这是因为像
std::decay::type
这样的成员类型别名是不可扣除的

template<typename T>
void call_me(std::decay_t<T>) {}

// won't work :(
// call_me(1);
模板
void call_me(std::decation_t){
//不起作用:(
//叫我(1);
我不认为您的类应该衰减类型。相反,您的类应该声明它需要对象类型,并将衰减移动到make函数中:

template <typename F> // requires std::is_object_v<F>
class WillInvoke
{
    static_assert(std::is_object_v<F>,
        "WillInvoke requires F to be an object type"
    );
public:
    WillInvoke(F f) : f(std::move(f)) { }

    void CallNow() { f(); }

private:
    F f;
};

template <typename F>
auto make_WillInvoke(F && f) -> WillInvoke<std::decay_t<F>>
{
    return WillInvoke<std::decay_t<F>>(std::forward<F>(f));
}
template//需要std::is\u object\u v
威林沃克级
{
静态断言(std::is_object_v,
“WillInvoke要求F是对象类型”
);
公众:
WillInvoke(F):F(std::move(F)){
void CallNow(){f();}
私人:
F;
};
模板
自动生成WillInvoke(F&F)->WillInvoke
{
返回WillInvoke(std::forward(f));
}

很好的一点是,在C++20中,可以取消对requires的注释,并让编译器在调用站点中强制执行。

这是因为像
std::decay::type这样的成员类型别名是不可扣除的

template<typename T>
void call_me(std::decay_t<T>) {}

// won't work :(
// call_me(1);
模板
void call_me(std::decation_t){
//不起作用:(
//叫我(1);
我不认为您的类应该衰减类型。相反,您的类应该声明它需要对象类型,并将衰减移动到make函数中:

template <typename F> // requires std::is_object_v<F>
class WillInvoke
{
    static_assert(std::is_object_v<F>,
        "WillInvoke requires F to be an object type"
    );
public:
    WillInvoke(F f) : f(std::move(f)) { }

    void CallNow() { f(); }

private:
    F f;
};

template <typename F>
auto make_WillInvoke(F && f) -> WillInvoke<std::decay_t<F>>
{
    return WillInvoke<std::decay_t<F>>(std::forward<F>(f));
}
template//需要std::is\u object\u v
威林沃克级
{
静态断言(std::is_object_v,
“WillInvoke要求F是对象类型”
);
公众:
WillInvoke(F):F(std::move(F)){
void CallNow(){f();}
私人:
F;
};
模板
自动生成WillInvoke(F&F)->WillInvoke
{
返回WillInvoke(std::forward(f));
}

很好的一点是,在C++20中,您可以取消注释requires,并让编译器在调用站点中强制执行它。

您使用
std::detacient\u t
到底想要实现什么?您使用
std::detacient\u t
到底想要实现什么?