GVKun编程网logo

将模板化参数包存储在std :: function对象(模板参数可以作为数据成员的类型)

5

最近很多小伙伴都在问将模板化参数包存储在std::function对象和模板参数可以作为数据成员的类型这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展c–boost::functi

最近很多小伙伴都在问将模板化参数包存储在std :: function对象模板参数可以作为数据成员的类型这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展c – boost :: function如何支持具有不同长度模板参数的模板类、c – std :: async可以调用std :: function对象吗?、c – std :: bind to std :: function?、c – std :: function typedef中的参数名称等相关知识,下面开始了哦!

本文目录一览:

将模板化参数包存储在std :: function对象(模板参数可以作为数据成员的类型)

将模板化参数包存储在std :: function对象(模板参数可以作为数据成员的类型)

您无法使用虚拟模板方法,这主要是您想要在std::function之后进行类型擦除的方法。

在控制您的库时,您会知道真正使用的每个原型,因此您可以创建一个符合您需求的记录器界面:

struct ILogger
{
    virtual ~ILogger() = default;

    virtual void write(severity_t,const std::string&) = 0;
    virtual void write(severity_t,const std::string&,int) = 0;
    virtual void write(severity_t,int,float) = 0;
    // ...
};

void set_logger(ILogger&); // custom point

然后提供一种方法,可以从可变参函数轻松创建类,例如:

template <typename Functor>
struct LoggerT : ILogger,Functor
{
    using Functor::Functor;
    using Functor::operator();

    void write(severity_t level,const std::string& format) override { (*this)(level,format);}
    void write(severity_t level,const std::string& format,int v1) override { (*this)(level,format,v1);}
    void write(severity_t level,int v1,const std::string& v2) override { (*this)(level,v1,v2);}
    void write(severity_t level,float v1) override { (*this)(level,v1);}
    // ...
};

template <typename Func>
LoggerT<Func> make_logger(Func func) { return {func}; }

然后您的客户只需要写:

struct SpdLogger {
    template <typename ... Ts>
    void operator () (severity_t level,const std::string& msg,Ts&& args...)
    {
        if (level == severity_t::warn)
        {
            spdlog::warn(msg,std::forward<Ts>(args)...);
        }
    }
};

int main()
{
    LoggerT<SpdLogger> logger;
    set_logger(logger);
    // ...
}

以及在具有常规lambda的C ++ 14中:

auto logger = make_logger([](severity_t level,auto&& args...)
    {
        if(level == severity_t::warn)
        {
            spdlog::warn(msg,decltype(args)(args)...); // decltype(args) is the forward
        }
    });
set_logger(logger);

c – boost :: function如何支持具有不同长度模板参数的模板类

c – boost :: function如何支持具有不同长度模板参数的模板类

我想使用boost预处理器来声明具有不同模板变量长度的模板类,基本上就像boost :: function那样.

#if !BOOST_PP_IS_ITErating

#ifndef D_EXAMPLE_H
#define D_EXAMPLE_H
#include <boost/function>
#include <boost/preprocessor/iteration/iterate.hpp>
#define BOOST_PP_IteraTION_ParaMS_1 (3,(1,2,"example.h"))
#include BOOST_PP_IteraTE()

#else
template<class T,BOOST_PP_ENUM_ParaMS(BOOST_PP_IteraTION(),class T)>
class Example
{
    boost::function<T,(BOOST_PP_ENUM_ParaMS(BOOST_PP_IteraTION(),T))> func;
};
#endif

上面的代码显然不会起作用,因为它在同一个头文件中声明了具有不同模板变量长度的同一个类.我想要实现的是包含一个文件并定义具有不同模板变量长度的类,就像boost :: function一样.

#include "example.h"
Example<int,int,float> example1;
Example<double,int> example2;

我查了一下boost :: function的代码,但我无法弄清楚它是如何工作的.有任何想法吗?

解决方法

您需要首先使用最多参数声明模板类,并使用除第一个参数之外的所有参数的默认值.然后可以将具有较少参数的模板类定义为主模板类的特化.例:

#include <iostream>

template<class A,class B = void,class C = void>
class Example
{
public:
    static const int x = 3;
};

template<class A,class B>
class Example<A,B,void>
{
public:
    static const int x = 2;
};

template<class A>
class Example<A,void,void>
{
public:
    static const int x = 1;
};

int main()
{
    Example<int,int> e3;
    Example<int,int> e2;
    Example<int> e1;
    std::cout << e3.x << e2.x << e1.x << std::endl;
}

c – std :: async可以调用std :: function对象吗?

c – std :: async可以调用std :: function对象吗?

是否可以使用std :: async调用使用std :: bind创建的函数对象.以下代码无法编译:
#include <iostream>
#include <future>
#include <functional>

using namespace std;

class Adder {
public:
    int add(int x,int y) {
        return x + y;
    }
};

int main(int argc,const char * argv[])
{
    Adder a;
    function<int(int,int)> sumFunc = bind(&Adder::add,&a,1,2);
    auto future = async(launch::async,sumFunc); // ERROR HERE
    cout << future.get();
    return 0;
}

错误是:

没有用于调用’async’的匹配函数:
候选模板被忽略:替换失败[使用Fp = std :: _ 1 :: function&,Args =<>]:’std :: _ 1 :: __ invoke_of,>中没有名为’type’的类型

是不是可以与std :: function对象使用异步,或者我做错了什么?

(这是使用Xcode 5和Apple LLVM 5.0编译器编译的)

解决方法

Is it possible to call function objects created with std::bind using std::async

是的,只要您提供正确数量的参数,就可以调用任何仿函数.

am I doing something wrong?

您将绑定函数(不带参数)转换为函数< int(int,int)>,它接受(并忽略)两个参数;然后尝试在没有参数的情况下启动它.

您可以指定正确的签名:

function<int()> sumFunc = bind(&Adder::add,2);

或者避免创建函数的开销:

auto sumFunc = bind(&Adder::add,2);

或根本不打扰绑定:

auto future = async(launch::async,&Adder::add,2);

或者使用lambda:

auto future = async(launch::async,[]{return a.add(1,2);});

c – std :: bind to std :: function?

c – std :: bind to std :: function?

我使用这个编译错误:
std::vector<std::function<int(int)>> functions;

std::function<int(int,int)> foo = [](int a,int b){};
std::function<int(int)> bar = std::bind(foo,2);

functions.push_back(bar);

我得到的错误是:

/usr/include/c++/4.6/functional:1764:40: error: no match for call to '(std::_Bind<std::function<int(int,int)>(int)>) (int)'

有人可以告诉我如何将std :: bind转换成std ::函数?

解决方法

std::function<int(int)> bar = std::bind(foo,2,std::placeholders::_1);

c – std :: function typedef中的参数名称

c – std :: function typedef中的参数名称

我知道我可以像这样输入一个 std::function

typedef std::function<void (const std::string&)> TextChangedHandler

是否允许在typedef中指定参数名称,以使其更加自我记录?例如:

typedef std::function<void (const std::string& text)> TextChangedHandler

我可以添加参数名称,它在Visual C 2010上编译得很好,但我想确保它符合C 03 / C 11标准.

解决方法

是.

这种指定函数类型而没有声明符来命名函数的形式在语法上是一个type-id(8.1):

type-id:
    type-specifier-seq abstract-declarator[opt]

abstract-declarator:
    ptr-operator abstract-declarator[opt]
    direct-abstract-declarator

direct-abstract-declarator:
    direct-abstract-declarator[opt] ( parameter-declaration-clause ) cv-qualifier-seq exception-specification
    direct-abstract-declarator[opt] [ constant-expression ]
    ( abstract-declarator )

parameter-declaration-clause语法与普通函数声明中的语法相同,它允许每个参数具有名称(声明符)或不具有(抽象声明符)(8.3.5):

parameter-declaration-clause:
    parameter-declaration-list[opt] ...[opt]
    parameter-declaration-list[opt],...

parameter-declaration-list:
    parameter-declaration
    parameter-declaration-list,parameter-declaration

parameter-declaration:
    decl-specifier-seq declarator
    decl-specifier-seq declarator = assignment-expression
    decl-specifier-seq abstract-declarator[opt]
    decl-specifier-seq abstract-declarator[opt] = assignment-expression

关于将模板化参数包存储在std :: function对象模板参数可以作为数据成员的类型的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于c – boost :: function如何支持具有不同长度模板参数的模板类、c – std :: async可以调用std :: function对象吗?、c – std :: bind to std :: function?、c – std :: function typedef中的参数名称等相关内容,可以在本站寻找。

本文标签: