标签: template-meta-programming

为什么is_swappable和is_nothrow_swappable不包含在C++ 11中?

我很惊讶地发现is_swappable<T>并且is_nothrow_swappable<T>不属于新的C++ 11 type_traits元函数.它们对于传播noexcept模板和确定是否可以为模板实现非抛出交换非常有用.

的libc ++推出其自己的内部版本:看__is_swappable和__is_nothrow_swappable在其版本type_traits的,它使大量的内部使用它们,但不会让他们提供给外部.

我最终将我自己的这些版本拼凑起来用于个人项目,这似乎有效,但我确定它会以某种方式破坏.

我很好奇这两个缺席,因为它们看起来非常重要.在C++ 11标准化过程中是否考虑过此功能,还是仅仅是一个未包含在内的疏忽?如果考虑到了什么,导致它没有被纳入最终标准(缺乏时间,实施问题等)?是否有缺陷报告或进化论文讨论这个问题?有没有计划在C++ 1Y中加入这些特性?某处有一个公认的"正确"版本吗?

c++ standards template-meta-programming c++11 libc++

19
推荐指数
1
解决办法
1274
查看次数

编译时浮点初始化的替代方法

我目前正致力于基于模板元编程的浮点运算实现.表示编译时浮点值的模板如下:

template<bool S , std::int16_t E , std::uint64_t M>
struct number{};
Run Code Online (Sandbox Code Playgroud)

由于使用硬编码的尾数,指数等初始化这些值是一个麻烦且容易出错的过程,我编写了一个模板,用于将十进制值转换为浮点值:

template<std::int64_t INT , std::uint64_t DECS>
struct decimal{};
Run Code Online (Sandbox Code Playgroud)

其中第一个参数表示积分部分,第二个参数表示小数位数.我认为这是一种常见且众所周知的方式.
然而,这种模式会遇到一些问题(如何输入负数小于一的数字?),其中最令我讨厌的事实之一就是没有办法在逗号之后输入零数字,即数字之类的0.00032.

我是C++ 11意识到的,我正在思考一个用户定义的文字+ decltype()方法(即使有一个宏#define FLOAT(x) decltype(x_MY_LITERAL)),但我不确定这种方法在所有情境中是否可行,我的意思是,如果文字+ decltype可在模板参数的上下文中进行评估.

即使这可行,我想知道是否有其他可能的方法来解决这个问题.那么,在编译时通过tmp进行浮点式初始化有哪些替代方案呢?


尝试替代方案:

仅仅为了完整性,我将描述我已经实施的替代方案,它们如何工作,以及它的功能和优点.问题本身仍然是开放的,允许任何人添加更多的替代品.

一些背景

首先,我将描述我使用过的功能,以确保每个人都能理解代码.

我的图书馆,Turbo Metaprogramming Library,基于三个原则:

  • 仅键入模板参数:完全通用的混合类型参数,值参数和模板模板参数非常难(几乎不可能),因此此库仅使用类型参数.无论何时需要使用值或模板,库都提供包装器以通过装箱传递这些参数.

  • 统一表达式评估:在编程语言中工作时的首要需求之一是评估表达式并获取其价值的方法.Turbo提供tml::eval元函数,它接受任何类型的表达式并返回(计算)其值.

  • 通过模板专业化定制的通用算法和元函数:每当我可以使用C++ 11模板别名来避免繁琐的typename ::type构造.我的惯例是在嵌套命名空间上定义实现模板(真正完成工作的元函数)impl,并在当前命名空间上定义结果的C++ 11模板别名.由于这些别名直接返回结果,因此它们无法在复杂表达式上进行求值(考虑元函数瞬时add<X,Y>,其中XY是lambda的变量.如果add是结果的别名,则不起作用,因为评估没有意义.如果我们需要表达式(元函数)而不是直接的结果,我的惯例是在func嵌套命名空间上为元函数添加别名.

这里有些例子:

using bits = tml::util::sizeof_bits<int>; //bits is a size_t integral …
Run Code Online (Sandbox Code Playgroud)

c++ floating-point templates template-meta-programming c++11

19
推荐指数
1
解决办法
1218
查看次数

Variadic模板和switch语句?

我有以下函数,可以采用不同类型的N个参数,并以这种方式将它们转发到每个单独类型模板化的N个函数(带有两个参数的示例):

template <typename T1, typename T2>
bool func(int& counter, T1 x1, T2 x2) {
    switch (counter) {
        case 0:
            if (func2<T1>(x1)) {
                counter++;
                return true;
            } else {
                return false;
            }
        case 1:
            if (func2<T2>(x2)) {
                counter++;
                return true;
            } else {
                return false;
            }
        default:
            return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想用可变参数模板编写这个函数,以便它可以以类型安全的方式处理任意数量的参数.我可以看到一个使用递归函数的解决方案,传递计数器和可变参数索引并比较它们的相等性,但这似乎产生的效率远远低于上面的switch语句(if-checks序列与跳转表相比) ).

这可以使用模板元编程有效地完成,还是我需要为每个arity提供重载?

c++ templates template-meta-programming variadic-templates c++14

19
推荐指数
1
解决办法
1929
查看次数

在编译时确定类型是否为STL容器

我想编写一个模板来确定类型是否是编译时的stl容器.

我有以下一点代码:

struct is_cont{};
struct not_cont{};

template <typename T>
struct is_cont { typedef not_cont result_t; };
Run Code Online (Sandbox Code Playgroud)

但我不确定如何创建必要的专业化std::vector<T,Alloc>, deque<T,Alloc>, set<T,Alloc,Comp>等...

c++ templates stl template-meta-programming

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

是否有可能在c ++中开发静态for循环?

是否有可能存在这样的事情?

template<int Channel>
void deduce_mask(Matrix const &src, int mask[])
{
    //I hope i could become a constant and the compiler would unroll the loop at compile time        
    for(int i = Channel; i != -1; --i)
    {            
        //mapper is a helper class which translate two and three dimension into one dimension index
        //constexpr makes it possible to find out the index at compile time
        mask[mapper(0, 1, i)] = src(row - 1, col)[i];
        mask[mapper(1, 1, i)] = src(row, col)[i];
        mask[mapper(2, 1, i)] …
Run Code Online (Sandbox Code Playgroud)

c++ for-loop template-meta-programming

18
推荐指数
3
解决办法
5452
查看次数

实现可变参数类型特征

介绍

我正在寻找一种模式将C++类型特征转换为它们的可变参数.一个方法来解决这个问题,将不胜感激,并生成编程模式,以自动执行任务将是理想的.

请考虑以下事项:

std::is_same<T, U>::value; 
Run Code Online (Sandbox Code Playgroud)

我想写一个像这样的特征:

std::are_same<T1, T2, T3, T4>::value; 
Run Code Online (Sandbox Code Playgroud)

目前的做法

实现这个非常简单are_same ; 寻求一般解决方案,我们可以为任何实现通用量化的可变特性提供工具:

template<template<class,class> class F, typename...Ts>
struct Univ;

template<template<class, class> class F, typename T, typename U, typename...Ts>
struct Univ<F, T, U, Ts...>
{
    static const int value = F<T, U>::value && Univ<F, U, Ts...>::value;
};

template<template<class, class> class F, typename T>
struct Univ<F, T>
{
    static const int value = 1;
};
Run Code Online (Sandbox Code Playgroud)

所以,例如are_same …

c++ templates generative-programming template-meta-programming c++11

18
推荐指数
1
解决办法
2195
查看次数

是否可以使用 CRTP 访问 C++ 中的子类型?

我有这个玩具示例,

template <typename TChild>
struct Base {
    template <typename T>
    using Foo = typename TChild::template B<T>;
};

struct Child : Base<Child> {
    template <typename T>
    using B = T;
};


using Bar = Child::Foo<int>;
Run Code Online (Sandbox Code Playgroud)

无法编译。目的是我有一个父类,它提供基于子类成员的类型计算。子类是通过 CRTP 提供的。然而线

using Foo = typename TChild::template B<T>;
Run Code Online (Sandbox Code Playgroud)

无法编译:

<source>: In instantiation of 'struct Base<Child>':
<source>:16:16:   required from here
<source>:13:11: error: invalid use of incomplete type 'struct Child'
   13 |     using Foo = typename TChild::template B<T>;
      |           ^~~
<source>:16:8: note: forward declaration of 'struct Child' …
Run Code Online (Sandbox Code Playgroud)

c++ crtp template-meta-programming c++14

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

如何将模板参数包参数限制为“链”序列?

假设我有两个课程:

\n
template <typename X, typename Y>\nclass Functor {};\n\ntemplate <typename Start, typename End, typename ...Functors>\nclass Template {};\n
Run Code Online (Sandbox Code Playgroud)\n

Template有以下限制:

\n
    \n
  • 全部Functors必须是类型Functor

    \n
  • \n
  • 所有内容都Functor必须按链式顺序排列,这样

    \n
      \n
    • 一个 Functor必须Start作为其第一个参数
    • \n
    • 最后 一个Functor必须End作为第二个参数
    • \n
    • 每个Functor\ 的第一个参数是前面它的第二个参数Functor
    • \n
    \n

    例如Functor<A,B>, Functor<B, C>, Functor<C, D>, ...等等。

    \n
  • \n
\n

例子:

\n

从...开始:char

\n

结尾为: …

c++ templates template-meta-programming c++-concepts c++20

18
推荐指数
3
解决办法
2218
查看次数

编译时间素数检查

我需要在编译时检查一些整数素数(将布尔值作为模板参数).

我写的代码做得很好:

#include <type_traits>
namespace impl {
    template <int n, long long i>
    struct PrimeChecker {
        typedef typename std::conditional<
                    (i * i > n),
                    std::true_type,
                    typename std::conditional<
                        n % i == 0,
                        std::false_type,
                        typename PrimeChecker<n, (i * i > n ) ? -1 : i + 1>::type
                    >::type
                >::type type;
    };
    template <int n>
    struct PrimeChecker<n, -1> {
        typedef void type;
    };
} // namespace impl
template<int n>
struct IsPrime {
    typedef typename impl::PrimeChecker<n, 2>::type type;
};

template<>
struct IsPrime<1> …
Run Code Online (Sandbox Code Playgroud)

c++ templates compile-time template-meta-programming c++11

17
推荐指数
2
解决办法
2150
查看次数

可变参数模板别名作为模板参数

首先是一些代码,然后是一些上下文,然后是问题:

template <typename T> using id = T;

template <template <typename...> class F, typename... T>
using apply1 = F <T...>;

template <template <typename...> class F>
struct apply2
{
    template <typename... T>
    using map = F <T...>;
};

// ...

cout << apply1 <id, int>() << endl;
cout << apply2 <id>::map <int>() << endl;
Run Code Online (Sandbox Code Playgroud)

clang 3.3和gcc 4.8.1都编译了这个没有错误,应用了标识元函数int,因此两个表达式都计算为默认值int(零).

id有一段template <typename>时间的事实apply1,apply2期待template <typename...>我首先关注我.然而,这是很方便的,这个例子的作品,因为否则像元函数apply1,apply2必须是这么多参与.

另一方面,这样的模板别名在现实世界的代码中引起严重的问题,我无法在这里重现:gcc频繁的内部编译器错误,以及clang的频繁出现意外行为(仅在更高级的SFINAE测试中).

经过几个月的试验和错误,我现在安装并尝试(实验)gcc 4.9.0上的代码,这里出现错误:

test.cpp: …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming variadic-templates c++11 template-aliases

17
推荐指数
1
解决办法
2598
查看次数