【问题标题】:c++ template non-type argument lambda functionc++模板非类型参数lambda函数
【发布时间】:2013-04-23 21:30:51
【问题描述】:

这行得通:

#include <functional>

template < bool (*F)( int ) > class Foo {};

bool fooFunc( int n ) { return true; }

int main( int argc, char* argv[] )
{
    auto a = Foo< fooFunc >();
}

但这不起作用,因为您无法将 lambda 转换为函数指针:

#include <functional>

template < bool (*F)( int ) > class Foo {};

auto barFunc = [] ( int n ) -> bool { return true; };

int main( int argc, char* argv[] )
{
    auto a = Foo< barFunc >();
}

这不起作用,因为您不能使用 std::function 作为模板非类型参数:

#include <functional>

template < std::function< bool( int ) > F > class Bar {};

auto barFunc = [] ( int n ) -> bool { return true; };

int main( int argc, char* argv[] )
{
    auto b = Bar< barFunc >();
}

那么如何创建一个能够接受 lambda 封装作为模板非类型参数的模板类?

【问题讨论】:

  • 请注意非类型模板参数的含义。你的意思不是简单地放template &lt;typename T&gt;吗?是不是因为这样做过于放宽了模板参数要求,无法满足您的需求?
  • 他的意思是一个(相对于类型)模板参数,例如:template &lt;int N&gt;
  • 我认为你试图在编译时做一些在一般情况下直到运行时才能完成的事情,这就是为什么“你不能使用 std::function 作为模板非类型参数”
  • 如果从[](int)-&gt;boolbool(*)(int) 的转换是constexpr,这很容易做到。
  • 要清楚,如果标准说“没有 lambda 捕获的 lambda 表达式的闭包类型有一个公共的非虚拟非显式 const 转换函数,指向具有相同的函数的指针参数和返回类型作为闭包类型的函数调用运算符。” constexpr 而不是 const 这将是可行的。但标准是保守的。我想不出为什么转换不应该是 constexpr 的技术原因,其他人可以吗?

标签: c++ templates c++11 lambda


【解决方案1】:

只需创建一个带有类型参数的类模板,并在实例化模板时使用decltype 来推断 lambda 的类型。

#include <functional>

template <typename Function> 
class Bar 
{ };

auto barFunc = [] ( int n ) -> bool { return true; };

int main()
{
    auto b = Bar<decltype(barFunc)>();
}


但请注意,lambda 不是默认可构造的,因此您可能需要添加更多代码来创建 Bar 的构造函数,该构造函数接受 lambda 的副本:

template <typename Function> 
class Bar 
{ 
    public:

    Bar(Function f) : m_function(f)
    { }

    private:

    Function m_function;
};

【讨论】:

    【解决方案2】:

    在您的第一个示例中,您需要添加一个指针,因为该函数没有衰减为一个。

    int main( int argc, char** )
    {
        auto a = Foo< std::add_pointer<decltype(fooFunc)>::type(0) >();
    }
    

    【讨论】:

    • 有趣。为什么std::add_pointer&lt;decltype(fooFunc)&gt;::type(0) 中需要(0)
    猜你喜欢
    • 2021-02-07
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    相关资源
    最近更新 更多