C++ Boost Parameter超详细讲解

目录
  • 一、说明
  • 二、示例代码

一、说明

Boost.Parameter 使得将参数作为键/值对传递成为可能。除了支持函数参数外,该库还支持模板参数。 Boost.Parameter 在您使用长参数列表并且参数的顺序和含义难以记住时特别有用。键/值对使得以任何顺序传递参数成为可能。因为每一个值都是通过一个键来传递的,所以各种值的含义也更加清晰。

二、示例代码

示例 53.1。作为键/值对的函数参数

#include <boost/parameter.hpp>
#include <string>
#include <iostream>
#include <ios>
BOOST_PARAMETER_NAME(a)
BOOST_PARAMETER_NAME(b)
BOOST_PARAMETER_NAME(c)
BOOST_PARAMETER_NAME(d)
BOOST_PARAMETER_NAME(e)
BOOST_PARAMETER_FUNCTION(
  (void),
  complicated,
  tag,
  (required
    (a, (int))
    (b, (char))
    (c, (double))
    (d, (std::string))
    (e, *)
  )
)
{
  std::cout.setf(std::ios::boolalpha);
  std::cout << a << '\n';
  std::cout << b << '\n';
  std::cout << c << '\n';
  std::cout << d << '\n';
  std::cout << e << '\n';
}
int main()
{
  complicated(_c = 3.14, _a = 1, _d = "Boost", _b = 'B', _e = true);
}

Example53.1

示例 53.1 定义了一个函数 complicated(),它需要五个参数。参数可以按任何顺序传递。 Boost.Parameter 提供了宏 BOOST_PARAMETER_FUNCTION 来定义这样的函数。

在可以使用 BOOST_PARAMETER_FUNCTION 之前,必须定义键/值对的参数。这是通过宏 BOOST_PARAMETER_NAME 完成的,它只是传递了一个参数名称。该示例使用 BOOST_PARAMETER_NAME 五次来定义参数名称 a、b、c、d 和 e。

请注意,参数名称是在命名空间标记中自动定义的。这应该避免与程序中的同名定义发生冲突。

定义参数名称后,BOOST_PARAMETER_FUNCTION 用于定义函数 complicated()。传递给 BOOST_PARAMETER_FUNCTION 的第一个参数是返回值的类型。这在示例中是无效的。请注意,类型必须用括号括起来——第一个参数是 (void)。

第二个参数是正在定义的函数的名称。第三个参数是包含参数名称的名称空间。在第四个参数中,访问参数名称以进一步指定它们。

在示例 53.1 中,第四个参数以 required 开头,这是一个使后面的参数成为必需的关键字。 required 后跟一对或多对,由参数名称和类型组成。将类型括在括号中很重要。

各种类型用于参数 a、b、c 和 d。例如,a 可用于将 int 值传递给 complicated()。没有为 e 给出类型。相反,使用星号,这意味着传递的值可以具有任何类型。 e 是一个模板参数。

将各种参数传递给 BOOST_PARAMETER_FUNCTION 后,定义函数体。像往常一样,这是在一对大括号之间完成的。可以在函数体中访问参数。它们可以像变量一样使用,在 BOOST_PARAMETER_FUNCTION 中分配类型。示例 53.1 将参数写入标准输出。

complicated() 是从 main() 调用的。参数以任意顺序传递给 complicated()。参数名称以下划线开头。 Boost.Parameter 使用下划线来避免与其他变量名称冲突。

注意:

要在 C++ 中将函数参数作为键/值对传递,您还可以使用命名参数习惯用法,它不需要像 Boost.Parameter 这样的库。

示例 53.2。可选功能参数

#include <boost/parameter.hpp>
#include <string>
#include <iostream>
#include <ios>
BOOST_PARAMETER_NAME(a)
BOOST_PARAMETER_NAME(b)
BOOST_PARAMETER_NAME(c)
BOOST_PARAMETER_NAME(d)
BOOST_PARAMETER_NAME(e)
BOOST_PARAMETER_FUNCTION(
  (void),
  complicated,
  tag,
  (required
    (a, (int))
    (b, (char)))
  (optional
    (c, (double), 3.14)
    (d, (std::string), "Boost")
    (e, *, true))
)
{
  std::cout.setf(std::ios::boolalpha);
  std::cout << a << '\n';
  std::cout << b << '\n';
  std::cout << c << '\n';
  std::cout << d << '\n';
  std::cout << e << '\n';
}
int main()
{
  complicated(_b = 'B', _a = 1);
}

BOOST_PARAMETER_FUNCTION 还支持定义可选参数。

在示例 53.2 中,参数 c、d 和 e 是可选的。这些参数使用可选关键字在 BOOST_PARAMETER_FUNCTION 中定义。

可选参数的定义类似于必需参数:参数名称后跟类型。像往常一样,类型被括在括号中。但是,可选参数需要有默认值。

通过调用 complicated(),仅传递参数 a 和 b。这些是唯一需要的参数。由于未使用参数 c、d 和 e,因此将它们设置为默认值。

除了 BOOST_PARAMETER_FUNCTION 之外,Boost.Parameter 还提供宏。例如,您可以使用 BOOST_PARAMETER_MEMBER_FUNCTION 来定义成员函数,并使用 BOOST_PARAMETER_CONST_MEMBER_FUNCTION 来定义常量成员函数。

您可以使用 Boost.Parameter 定义函数,尝试自动为参数赋值。在这种情况下,您不需要传递键/值对——只传递值就足够了。如果所有值的类型不同,Boost.Parameter 可以检测出哪个值属于哪个参数。这可能需要您对模板元编程有更深入的了解。

示例 53.3。作为键/值对的模板参数

#include <boost/parameter.hpp>
#include <boost/mpl/placeholders.hpp>
#include <type_traits>
#include <typeinfo>
#include <iostream>
BOOST_PARAMETER_TEMPLATE_KEYWORD(integral_type)
BOOST_PARAMETER_TEMPLATE_KEYWORD(floating_point_type)
BOOST_PARAMETER_TEMPLATE_KEYWORD(any_type)
using namespace boost::parameter;
using boost::mpl::placeholders::_;
typedef parameters<
  required<tag::integral_type, std::is_integral<_>>,
  required<tag::floating_point_type, std::is_floating_point<_>>,
  required<tag::any_type, std::is_object<_>>
> complicated_signature;
template <class A, class B, class C>
class complicated
{
public:
  typedef typename complicated_signature::bind<A, B, C>::type args;
  typedef typename value_type<args, tag::integral_type>::type integral_type;
  typedef typename value_type<args, tag::floating_point_type>::type
    floating_point_type;
  typedef typename value_type<args, tag::any_type>::type any_type;
};
int main()
{
  typedef complicated<floating_point_type<double>, integral_type<int>,
    any_type<bool>> c;
  std::cout << typeid(c::integral_type).name() << '\n';
  std::cout << typeid(c::floating_point_type).name() << '\n';
  std::cout << typeid(c::any_type).name() << '\n';
}

Example53.3

示例 53.3 使用 Boost.Parameter 将模板参数作为键/值对传递。与函数一样,可以按任何顺序传递模板参数。

该示例定义了一个类 complicated,它需要三个模板参数。因为参数的顺序无关紧要,所以它们称为 A、B 和 C。A、B 和 C 不是访问类模板时将使用的参数名称。与函数一样,参数名称是使用宏定义的。对于模板参数,使用 BOOST_PARAMETER_TEMPLATE_KEYWORD。示例 53.3 定义了三个参数名称 integral_type、floating_point_type 和 any_type。

定义参数名称后,您必须指定可以传递的类型。例如,参数 integral_type 可用于传递 int 或 long 等类型,但不能传递 std::string 等类型。 boost::parameter::parameters 用于创建引用参数名称的签名,并定义可以与每个参数一起传递的类型。

boost::parameter::parameters 是一个描述参数的元组。必需参数标有 boost::parameter::required。

boost::parameter::required 需要两个参数。第一个是使用 BOOST_PARAMETER_TEMPLATE_KEYWORD 定义的参数名称。第二个标识参数可能设置的类型。例如,integral_type 可以设置为整数类型。此要求用 std::is_integral<_> 表示。 std::is_integral<_> 是一个基于 Boost.MPL 的 lambda 函数。 boost::mpl::placeholders::_ 是这个库提供的占位符。如果将设置了 integral_type 的类型传递给 std::is_integral 而不是 boost::mpl::placeholders::_,并且结果为真,则使用有效类型。其他参数 floating_point_type 和 any_type 的要求以类似方式定义。

创建签名并将其定义为 complicated_signature 后,复杂类将使用它。首先,使用 complicated_signature::bind 将签名绑定到模板参数 A、B 和 C。新类型 args 表示传递的模板参数与模板参数必须满足的要求之间的联系。接下来,访问 args 以获取参数值。这是通过 boost::parameter::value_type 完成的。 boost::parameter::value_type 期望参数和要传递的参数。该参数确定创建的类型。在示例 53.3 中,类 complicated 中的类型定义 integral_type 用于获取通过参数 integral_type 传递给 complicated 的类型。

main() 访问复杂的实例化类。参数 integral_type 设置为 int,floating_point_type 设置为 double,any_type 设置为 bool。传递的参数的顺序无关紧要。然后通过 typeid 访问类型定义 integral_type、floating_point_type 和 any_type 以获取它们的基础类型。该示例使用 Visual C++ 2013 编译,将 int、double 和 bool 写入标准输出。

示例 53.4。可选模板参数

#include <boost/parameter.hpp>
#include <boost/mpl/placeholders.hpp>
#include <type_traits>
#include <typeinfo>
#include <iostream>
BOOST_PARAMETER_TEMPLATE_KEYWORD(integral_type)
BOOST_PARAMETER_TEMPLATE_KEYWORD(floating_point_type)
BOOST_PARAMETER_TEMPLATE_KEYWORD(any_type)
using namespace boost::parameter;
using boost::mpl::placeholders::_;
typedef parameters<
  required<tag::integral_type, std::is_integral<_>>,
  optional<tag::floating_point_type, std::is_floating_point<_>>,
  optional<tag::any_type, std::is_object<_>>
> complicated_signature;
template <class A, class B = void_, class C = void_>
class complicated
{
public:
  typedef typename complicated_signature::bind<A, B, C>::type args;
  typedef typename value_type<args, tag::integral_type>::type integral_type;
  typedef typename value_type<args, tag::floating_point_type, float>::type
    floating_point_type;
  typedef typename value_type<args, tag::any_type, bool>::type any_type;
};
int main()
{
  typedef complicated<floating_point_type<double>, integral_type<short>> c;
  std::cout << typeid(c::integral_type).name() << '\n';
  std::cout << typeid(c::floating_point_type).name() << '\n';
  std::cout << typeid(c::any_type).name() << '\n';
}

示例 53.4 介绍了可选的模板参数。签名使用 boost::parameter::optional 作为可选的模板参数。 complicated 中的可选模板参数设置为 boost::parameter::void_,并且 boost::parameter::value_type 被赋予默认值。此默认值是可选参数将设置为的类型,如果类型未另外设置的话。

complicated 在 main() 中实例化。这次只使用参数 integral_type 和 floating_point_type。 any_type 未使用。该示例使用 Visual C++ 2013 编译,将 integral_type 的 short、floating_point_type 的 double 和 any_type 的 bool 写入标准输出。

Boost.Parameter 可以自动检测模板参数。您可以创建允许将类型自动分配给参数的签名。与函数参数一样,需要对模板元编程有更深入的了解才能做到这一点。

到此这篇关于C++ Boost Parameter超详细讲解的文章就介绍到这了,更多相关C++ Boost Parameter内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++ Boost Random随机函数详解

    目录 一.说明 二.示例代码 一.说明 Boost.Random 库提供了许多随机数生成器,可让您决定应如何生成随机数.在 C++ 中,始终可以使用来自 cstdlib 的 std::rand() 生成随机数.但是,使用 std::rand() 生成随机数的方式取决于标准库的实现方式. 当包含头文件 boost/random.hpp 时,您可以使用 Boost.Random 中的所有随机数生成器和其他类和函数. 该库的大部分已添加到 C++11 的标准库中.如果您的开发环境支持 C++11,您可

  • C++ Boost System超详细讲解

    目录 一.说明 二.关于 Boost.System库 一.说明 以下库支持错误处理. Boost.System 提供类来描述和识别错误.自 C++11 以来,这些类已成为标准库的一部分. Boost.Exception 使得在抛出异常后附加数据成为可能. 二.关于 Boost.System库 Boost.System Boost.System 是一个库,本质上定义了四个类来识别错误.所有四个类都已添加到 C++11 的标准库中.如果您的开发环境支持 C++11,则无需使用 Boost.Syste

  • C++ Boost Accumulators累加器详细讲解

    Boost.Accumulators Boost.Accumulators 提供了处理样本的类.例如,您可以找到最大或最小的样本,或者计算所有样本的总和.虽然标准库支持其中一些操作,但 Boost.Accumulators 还支持统计计算,例如均值和标准差. 该库称为 Boost.Accumulators,因为累加器是一个基本概念.累加器是一个容器,每次插入一个值时都会计算出一个新的结果.该值不一定存储在累加器中.相反,累加器在输入新值时不断更新中间结果. Boost.Accumulators

  • C++ Boost Exception超详细讲解

    Boost.Exception 库提供了一种新的异常类型 boost::exception,它允许您在抛出异常后将数据添加到异常中.此类型在 boost/exception/exception.hpp 中定义.由于 Boost.Exception 将其类和函数分布在多个头文件中,以下示例访问主头文件 boost/exception/all.hpp 以避免一个接一个地包含头文件. Boost.Exception 支持 C++11 标准的机制,该机制将异常从一个线程传输到另一个线程. boost::

  • C++ Boost Foreach超详细分析讲解

    目录 一.说明 二.示例代码 2.1 最简单的代码 2.2 使用BOOST_FOREACH与BOOST_REVERSE_FOREACH 三.BOOST_FOREACH特点和应用范围 四.遍历循环控制 一.说明 Boost.Foreach Boost.Foreach 提供了一个宏来模拟 C++11 中基于范围的 for 循环.您可以使用在 boost/foreach.hpp 中定义的宏 BOOST_FOREACH 来迭代序列而不使用迭代器.如果你的开发环境支持C++11,可以忽略Boost.For

  • C++ Boost Conversion超详细讲解

    目录 一.说明 二.示例和代码 三.更多示例代码 一.说明 Boost.Conversion 在头文件 boost/cast.hpp 中定义了转换运算符 boost::polymorphic_cast 和 boost::polymorphic_downcast.它们旨在更精确地处理类型转换——通常使用 dynamic_cast 完成. 库由两个文件组成.分别在boost/cast.hpp文件中定义了boost::polymorphic_cast和boost::polymorphic_downca

  • C++ Boost log日志库超详细讲解

    目录 一.说明 二.库Boost.Log 一.说明 应用程序库是指通常专门用于独立应用程序开发而不用于库开发的库. Boost.Log 是一个日志库. Boost.ProgramOptions 是一个用于定义和解析命令行选项的库. Boost.Serialization 允许您序列化对象,例如,将它们保存到文件或从文件加载它们. Boost.Uuid 支持使用 UUID. 具体内容 62. Boost.Log 63. Boost.ProgramOptions 64. Boost.Serializ

  • C++ Boost ProgramOptions超详细讲解

    目录 一.说明 二.示例Boost.ProgramOptions 一.说明 Boost.ProgramOptions Boost.ProgramOptions 是一个可以轻松解析命令行选项的库,例如,控制台应用程序.如果您使用图形用户界面开发应用程序,命令行选项通常并不重要. 要使用 Boost.ProgramOptions 解析命令行选项,需要以下三个步骤: 定义命令行选项.您给它们命名并指定哪些可以设置为一个值.如果命令行选项被解析为键/值对,您还可以设置值的类型——例如,它是字符串还是数字

  • C++ Boost Parameter超详细讲解

    目录 一.说明 二.示例代码 一.说明 Boost.Parameter 使得将参数作为键/值对传递成为可能.除了支持函数参数外,该库还支持模板参数. Boost.Parameter 在您使用长参数列表并且参数的顺序和含义难以记住时特别有用.键/值对使得以任何顺序传递参数成为可能.因为每一个值都是通过一个键来传递的,所以各种值的含义也更加清晰. 二.示例代码 示例 53.1.作为键/值对的函数参数 #include <boost/parameter.hpp> #include <strin

  • C++ Boost Lockfree超详细讲解使用方法

    目录 一.说明 二.示例和代码 Boost.Lockfree 一.说明 Boost.Lockfree 提供线程安全和无锁容器.可以从多个线程访问此库中的容器,而无需同步访问. 在 1.56.0 版本中,Boost.Lockfree 只提供了两个容器:boost::lockfree::queue 类型的队列和 boost::lockfree::stack 类型的栈.对于队列,可以使用第二个实现:boost::lockfree::spsc_queue.此类针对只有一个线程写入队列和只有一个线程从队列

  • C++ Boost ScopeExit超详细讲解

    目录 一.提要 二.退出作用域(Boost.ScopeExit) 2.1 范例1.UsingBOOST_SCOPE_EXIT 2.2 示例2.Boost.ScopeExit和C++11的lambda函数 2.3 示例3.特点BOOST_SCOPE_EXIT 三.练习 一.提要 资源有很多种,每种都封装一套,还是挺繁琐的!对于比较少使用或者一个程序很可能只会用一次的资源,我们不想封装,在这种情况下用Boost.ScopeExit. 二.退出作用域(Boost.ScopeExit) 库 Boost.

  • C++ Boost Uuid超详细讲解

    目录 一.说明 二.Boost.Uuid库示例和代码 一.说明 Boost.Uuid 为 UUID 提供生成器. UUID 是不依赖于中央协调实例的通用唯一标识符.例如,没有数据库存储所有生成的 UUID,可以检查这些 UUID 是否使用了新的 UUID. UUID 由必须唯一标识组件的分布式系统使用.例如,Microsoft 使用 UUID 来识别 COM 世界中的接口.对于为 COM 开发的新接口,可以轻松分配唯一标识符. UUID 是 128 位数字.存在多种生成 UUID 的方法.例如,

  • C++ Boost Archive超详细讲解

    目录 一.说明 二.关于Archive库 一.说明 对Boost.Serialization库的应用,存在如下内容: Archive Pointers and References Serialization of Class Hierarchy Objects Wrapper Functions for Optimization Boost.Serialization 库可以将 C++ 程序中的对象转换为可以保存和加载以恢复对象的字节序列.有不同的数据格式可用于定义生成字节序列的规则. Boo

  • C++ Boost Utility超详细讲解

    目录 一.说明 二.Boost.Utility库示例和代码 一.说明 Boost.Utility 库是杂项.有用的类和函数的集合,它们太小而无法在独立库中维护.虽然实用程序很小并且可以快速学习,但它们完全无关.与其他章节中的示例不同,此处的代码示例不是相互构建的,因为它们是独立的实用程序. 虽然大多数实用程序都在 boost/utility.hpp 中定义,但有些实用程序有自己的头文件.以下示例包括所介绍的实用程序的相应头文件. 二.Boost.Utility库示例和代码 示例 69.1.使用

  • C++ Boost Assign超详细讲解

    目录 说明 Exercise 说明 Boost.Assign Boost.Assign 库提供了帮助函数来初始化容器或向容器添加元素.如果需要将许多元素存储在一个容器中,这些函数尤其有用.多亏了 Boost.Assign 提供的函数,您不需要重复调​​用像 push_back() 这样的成员函数来将元素一个一个地插入到容器中. 如果您使用支持 C++11 的开发环境,则可以从初始化列表中获益.通常您可以将任意数量的值传递给构造函数来初始化容器.多亏了初始化列表,你不必依赖 C++11 的 Boo

  • C++ Boost Format超详细讲解

    Boost.Format Boost.Format 提供了函数 std::printf() 的替代品. std::printf() 源自 C 标准并允许格式化数据输出.但是,它既不是类型安全的,也不是可扩展的. Boost.Format 提供了一种类型安全且可扩展的替代方案. Boost.Format 提供了一个名为 boost::format 的类,该类在 boost/format.hpp 中定义.与 std::printf() 类似,将包含用于控制格式的特殊字符的字符串传递给 boost::

随机推荐