标签: boost-mpl

Boost :: MPL的实际使用示例?

你能否分享Boost :: MPL用法的任何实际例子(lambdas除外),只是为了让我更好地理解它的用途和实际应用领域?MPL文档教程有一个维度分析示例,但也许是因为它是一个这样的学术示例,它没有让我感觉到Boost :: MPL以及何时可以有效地使用它.

c++ boost boost-mpl

27
推荐指数
5
解决办法
1万
查看次数

松耦合隐式转换

类型在语义上等效时,隐式转换非常有用.例如,假设两个库以相同的方式实现类型,但在不同的命名空间中.或者只是一种大多数相同的类型,除了一些语义糖在这里和那里.现在,您无法将一种类型传递给设计为使用另一种的函数(在其中一个库中),除非该函数是模板.如果不是,你必须以某种方式将一种类型转换为另一种类型.这应该是微不足道的(或者其他类型在后面都不是那么相同!)但是调用转换显然会使代码膨胀,而且函数调用几乎毫无意义.虽然这样的转换函数实际上可能会复制一些值,但它们从高级"程序员"的角度来看基本上什么都不做.

隐式转换构造函数和运算符显然可以提供帮助,但它们引入了耦合,因此其中一种类型必须知道另一种类型.通常,至少在处理库时,情况并非如此,因为其中一种类型的存在使另一种类型变得冗余.此外,您不能总是更改库.

现在我看到有关如何在用户代码中进行隐式转换的两个选项:

  1. 第一个是提供代理类型,它为所有涉及的类型实现转换操作符和转换构造函数(和赋值),并始终使用它.

  2. 第二个需要对库进行最小的更改,但允许很大的灵活性:为每个可以在外部选择启用的相关类型添加转换构造函数.

例如,对于类型A添加构造函数:

template <class T> A(
  const T& src,
  typename boost::enable_if<conversion_enabled<T,A>>::type* ignore=0
)
{
  *this = convert(src);
}
Run Code Online (Sandbox Code Playgroud)

和一个模板

template <class X, class Y>
struct conversion_enabled : public boost::mpl::false_ {};
Run Code Online (Sandbox Code Playgroud)

默认情况下禁用隐式转换.

然后要启用两种类型之间的转换,请专门化模板:

template <> struct conversion_enabled<OtherA, A> : public boost::mpl::true_ {};
Run Code Online (Sandbox Code Playgroud)

并实现一个convert可以通过ADL找到的函数.

我个人更喜欢使用第二种变体,除非有强烈的反对意见.

现在回答实际问题:关联隐式转换类型的首选方法是什么?我的建议是好主意吗?两种方法都有任何缺点吗?允许这样的转换是危险的吗?如果库类实现者通常会提供第二种方法,那么它们的类型很可能会被软件复制,而这些软件很可能与它们一起使用(我在考虑使用3d渲染中间件,其中大多数软件包实现了3D向量).

c++ boost-mpl enable-if

25
推荐指数
1
解决办法
1061
查看次数

如何在C++中为MPL向量的所有成员显式实例化模板?

请考虑以下头文件:

// Foo.h
class Foo {
    public: 
        template <typename T>
        void read(T& value);
};
Run Code Online (Sandbox Code Playgroud)

我想Foo::read在源文件中显式实例化成员函数模板,包括在boost::mpl::vector:

// Foo.cc
#include <boost/mpl/vector.hpp>
#include <boost/mpl/begin_end.hpp>
#include "Foo.h"

template <typename T>
void Foo::read(T& value) { /* do something */ }

typedef boost::mpl::vector<int, long, float> types;

// template Foo::read<int  >(int&);
// template Foo::read<long >(long&);
// template Foo::read<float>(float&);

// instantiate automatically ???
Run Code Online (Sandbox Code Playgroud)

可能吗?谢谢,丹尼尔.

编辑

我找到了一些解决方案 - 似乎Foo::read<T>在结构的构造函数中指定一个指针,然后声明该变量,导致实例化:

// intermezzo
template <typename T> struct Bar {
    Bar<T>() {
        void (Foo::*funPtr)(T&) = &Foo::read<T>; …
Run Code Online (Sandbox Code Playgroud)

c++ boost vector boost-mpl explicit-instantiation

20
推荐指数
1
解决办法
2066
查看次数

是否可以在运行时迭代mpl :: vector而无需实例化向量中的类型?

通常,我会使用boost::mpl::for_each<>()遍历a boost::mpl::vector,但这需要一个带有模板函数的仿函数,如下所示:

template<typename T> void operator()(T&){T::staticCall();}

我的这个问题是我不希望的物体T被实例化也for_each<>.我根本不需要T参数operator().有没有办法实现这一点,或者替代方法for_each<>是不将类型为T的对象传递给模板函数?

最理想的是,我希望operator()定义如下所示:

template<typename T> void operator()(){T::staticCall();}

当然,我不希望在通话之前对T进行实例化.任何其他提示/建议也欢迎.

c++ foreach boost vector boost-mpl

18
推荐指数
2
解决办法
5154
查看次数

C++在编译时将整数转换为字符串

我想做这样的事情:

template<int N>
char* foo() {
  // return a compile-time string containing N, equivalent to doing
  // ostringstream ostr; 
  // ostr << N;
  // return ostr.str().c_str();
}
Run Code Online (Sandbox Code Playgroud)

似乎boost MPL库可能允许这样但我无法弄清楚如何使用它来实现这一点.这可能吗?

c++ string templates boost boost-mpl

17
推荐指数
4
解决办法
8441
查看次数

使用boost :: mpl的类型列表的排列

我正在尝试创建一个包含给定类型列表的排列的列表.

下面的代码似乎起作用,虽然没有预期的结果,当我使用指定的列表而不是通过从实际输入中删除来生成新列表.下面的permutation_helper和broken_helper之间的区别证明了这一点.

有谁知道为什么mpl::remove在这种情况下似乎没有像预期的那样发挥作用?

#include <boost/mpl/list.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/remove.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/equal.hpp>

namespace mpl = boost::mpl;

struct test_type1 {};
struct test_type2 {};
struct test_type3 {};

template< typename T >
struct permutations;

template <typename value>
struct permutations<mpl::list1< value > >: mpl::list1<mpl::list1< value > > {};

template< typename value, typename T>
struct permutation_helper: 
  mpl::transform< typename permutations< 
      mpl::list1<test_type3> >::type, 
    mpl::push_front< mpl::_1, value> > { };

template< typename value, typename T>
struct broken_helper:
  mpl::transform< typename …
Run Code Online (Sandbox Code Playgroud)

c++ boost metaprogramming boost-mpl

15
推荐指数
1
解决办法
1520
查看次数

boost mpl string

您好在boost mpl文档中我发现了mpl :: string和以下示例:

typedef mpl::string<'hell','o wo','rld'> hello;
Run Code Online (Sandbox Code Playgroud)

我有点惊讶,因为我认为在C或C++中我们不能在角色之间有多个角色'

这是正常而有效的吗?

c++ boost character boost-mpl

13
推荐指数
1
解决办法
1189
查看次数

通过缓存元函数优化编译时性能

假设我有以下元函数:

template <typename T>
struct make_pair {
    using type = std::pair<
        typename std::remove_reference<T>::type,
        typename std::remove_reference<T>::type
    >;
};
Run Code Online (Sandbox Code Playgroud)

相反,它会提高编译速度(或其他)吗?

template <typename T>
struct make_pair {
    using without_reference = typename std::remove_reference<T>::type;
    using type = std::pair<without_reference, without_reference>;
};
Run Code Online (Sandbox Code Playgroud)

我看到两种可能性:

  1. 编译器每次看到它都必须做一些工作typename std::remove_reference<T>::type.使用中间别名具有某种"缓存"行为,这允许编译器只执行一次工作.

  2. 编译时性能是根据编译器必须执行的模板实例化的数量来衡量的.因为std::remove_reference<T>::type引用的类型相同std::remove_reference<T>::type,所以在这两种情况下只需要一个模板实例化,因此两个实现都是等效的WRT编译时性能.

我认为B是对的,但我想确定一下.如果答案结果是编译器特定的,我最感兴趣的是知道Clang和GCC的答案.

编辑:

我对测试程序的编译进行了基准测试,以便使用一些数据.测试程序做了类似的事情:

template <typename ...> struct result;    

template <typename T>
struct with_cache {
    using without_reference = typename std::remove_reference<T>::type;
    using type = result<without_reference, ..., without_reference>;
};

template <typename T>
struct without_cache {
    using type …
Run Code Online (Sandbox Code Playgroud)

c++ templates instantiation boost-mpl template-meta-programming

13
推荐指数
1
解决办法
685
查看次数

C++ 14类型列表,任何理由更喜欢"自由函数"到"方法",反之亦然?

我看到了在C++ 11/14中实现类型列表的两种可能的样式,我很好奇是否有任何理由偏爱另一种.这里概述了第一种技术,并在Boost的MPL库中进行了建模.在这种风格中,您可以定义元"自由函数"(使用声明的顶级),它们接收类型列表并对其进行操作.以下是如何实现std :: transform的元版本,它适用于类型而不是第一种样式中的值:

    template <typename... Args>
    struct type_list;

    namespace impl
    {
        template <template <typename...> class F, class L>
        struct transform_impl;

        template <template <typename...> class F, template <typename...> class L, typename... T>
        struct transform_impl<F, L<T...>>
        {
            using type = L<typename F<T>::type...>;
        };
    }

    template <template <typename...> class F, class L>
    using transform = typename impl::transform_impl<F, L>::type;
Run Code Online (Sandbox Code Playgroud)

第二种方式是定义元'方法'(使用类型列表结构中的声明).以下是变换在该样式中的外观:

    template <typename... Args>
    struct type_list {
        // ... other 'methods'

        template<template<class> class Wrapper>
        using transform =
            type_list<Wrapper<Args>...>;

        // ... …
Run Code Online (Sandbox Code Playgroud)

c++ boost-mpl template-meta-programming c++11 c++14

13
推荐指数
1
解决办法
1067
查看次数

推动MPL占位符和Lambda

我目前正在使用boost :: mpl对概念样本进行一些证明,并且在理解lambda函数如何使用占位符方面遇到了一些困难.

我意识到我可以将metafunctions包装在元函数类中,以使更高阶函数能够访问嵌套的apply函数,并且已经意识到你可以通过使用mpl :: lambda包装允许占位符的元函数来避免这种努力.

这实际上是如何工作的?我无法将我的头包裹在lamda和占位符实际上在封面下做什么.

c++ lambda boost boost-mpl template-meta-programming

11
推荐指数
1
解决办法
1527
查看次数