标签: template-meta-programming

C++中Vector的实现

我最近写了一个STL Vector的实现作为编程练习.该程序编译但我收到一个奇怪的错误说:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Run Code Online (Sandbox Code Playgroud)

我以前从来没有想过这个错误,也不确定在我的实现中究竟应该改变什么才能使它正常运行.

有人可以查看我的代码,看看在这个特定情况下是否有任何东西突然出现错误?对不起,我不能更具体,我不知道在哪里看自己,提前谢谢.

#include <iostream>
#include <string>
#include <cassert>
#include <algorithm>

using namespace std;

template <class T>
class Vector
{
public:

   typedef T * iterator;

   Vector();
   Vector(unsigned int size);
   Vector(unsigned int size, const T & initial);
   Vector(const Vector<T> & v);      
   ~Vector();

   unsigned int capacity() const;
   unsigned int size() const;
   bool empty() const;
   iterator begin();
   iterator end();
   T & front();
   T & back();
   void push_back(const T & value); 
   void pop_back(); …
Run Code Online (Sandbox Code Playgroud)

c++ stl exception vector template-meta-programming

10
推荐指数
2
解决办法
5万
查看次数

是否可以将函数模板作为模板参数传递?

让我们假设,我们有一个模板功能:

template<typename T1, typename T2, typename T3>
T3 such_fun(T1 a, T2 b) {
    // do something...
}
Run Code Online (Sandbox Code Playgroud)

现在我们想将它用作另一个模板中的参数,例如像那样

template<typename T1, template<typename, typename, typename> some_function>
void big_fun(T1 a) {
   // some code...
   a = some_function<T1, T1, T1>(a, a);
   // some code...
}
Run Code Online (Sandbox Code Playgroud)

可能吗?

我知道我可以使用带有defined()运算符的结构.我只是对功能感到好奇.

编辑:

当我写这个问题时,我的朋友发现了一个部分解决方案:

template<typename T1, T1 (*some_function)(T1, T1)>
void big_fun(T1 a) {
   // some code...
   a = some_function(a, a);
   // some code...
}
Run Code Online (Sandbox Code Playgroud)

但是仍然 - 如果没有在调用之前实现函数类型的实现,我很好奇.例如 - 我可能想要使用各种类型组合调用传递的模板:

template<typename T1, typename T2, template<typename, typename, typename> some_function>
void big_fun(T1 …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-meta-programming

10
推荐指数
1
解决办法
261
查看次数

如何在编译时从类型创建静态字符串

我有一堆有名字的类型.(它们有更多功能,但为了讨论起见,只有名称是相关的.)这些类型及其名称是在编译时使用宏设置的:

#define DEFINE_FOO(Foo_)                        \
    struct Foo_ : public foo_base<Foo_> {       \
      static char const* name() {return #Foo_;} \
    }
Run Code Online (Sandbox Code Playgroud)

然后将这些类型组合在编译时列表(经典的简单递归编译时列表)中,我需要通过连接其对象的名称来创建列表的名称:

template<class Foo, class Tail = nil>
struct foo_list {
  static std::string name_list() {return Foo::name() + "-" + Tail::name();}
};
template<class Foo>
struct foo_list<Foo,nil> {
  static std::string name_list() {return Foo::name();}
};
Run Code Online (Sandbox Code Playgroud)

代码在这里归结为它可能包含错误的程度,但实际上这很好用.

除了它在运行时创建然后复制相当长的字符串,这些字符串表示在编译时实际上是众所周知的类型.由于这是一个在嵌入式设备上运行的性能相当敏感的代码,我想改变这一点

  1. 列表的字符串理想地是在编译时创建的,或者,如果没有办法在运行时创建它,并且
  2. 我只需要复制一个指向C字符串的指针,因为根据#1,字符串在内存中是固定的.
  3. 这与C++ 03一起编译,我们现在一直坚持使用它.

我怎样才能做到这一点?

(如果这扩大了可用于此的脏技巧:foo只能通过代码创建和读取对象的foo_list名称,并且只有名称字符串应该是人类可读的.)

c++ templates template-meta-programming

10
推荐指数
1
解决办法
1840
查看次数

Swift中的元编程

来自C++,我试图在Swift中做一些元编程.例如,我想实现一个添加两个数字的元函数.我尝试过这样的事情:

protocol IntWrapper {
    class var value: Int { get }
}

struct A: IntWrapper {
    static let value = 5
}

struct B: IntWrapper {
    static let value = 7
}

struct Sum<T: IntWrapper, U: IntWrapper>: IntWrapper {
    static let value = T.value + U.value
}
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用:Xcode抱怨T.Type没有成员value(或者有时只是崩溃).

如何实现这样的功能?

generics template-meta-programming swift

10
推荐指数
1
解决办法
2306
查看次数

比较两组类型是否相等

如何检查两个参数包是否相同,忽略它们的内部顺序?

到目前为止,我只有框架(使用std::tuple),但没有功能.

#include <tuple>
#include <type_traits>

template <typename, typename>
struct type_set_eq : std::false_type
{
};

template <typename ... Types1, typename ... Types2>
struct type_set_eq<std::tuple<Types1...>, std::tuple<Types2...>>
    : std::true_type
{
    // Should only be true_type if the sets of types are equal
};

int main() {
    using t1 = std::tuple<int, double>;
    using t2 = std::tuple<double, int>;
    using t3 = std::tuple<int, double, char>;

    static_assert(type_set_eq<t1, t1>::value, "err");
    static_assert(type_set_eq<t1, t2>::value, "err");
    static_assert(!type_set_eq<t1, t3>::value, "err");
}
Run Code Online (Sandbox Code Playgroud)

每个类型不允许在一个集合中出现多次.

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

10
推荐指数
2
解决办法
988
查看次数

c ++从decltype返回类型中删除noexcept

#include <functional>
#include <sys/types.h>
#include <sys/socket.h>


std::function<decltype(::bind)> mockbind = ::bind;

int main()
{
}
Run Code Online (Sandbox Code Playgroud)

上面的代码适用于我编译的大多数平台.但是在使用g ++ - 7的ubuntu 14.04上我收到一个错误:

X.cpp:7:65: error: variable ‘std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind’ has initializer but incomplete type
 std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind;
                                                                 ^~~~~~~~
Run Code Online (Sandbox Code Playgroud)

现在,如果我手动去改变类型 mockbind

std::function<int(int, const sockaddr*, unsigned int) noexcept> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,我得到了同样的错误:
现在如果我删除了noexcept

std::function<int(int, const sockaddr*, unsigned int)> mockbind = ::bind;
Run Code Online (Sandbox Code Playgroud)

它按预期编译.

所以问题是我可以应用一些模板代码来删除noexcept返回的类型decltype并使其按预期工作.

c++ decltype template-meta-programming c++17

10
推荐指数
1
解决办法
487
查看次数

如何在C++中传递参数包?

请考虑以下示例:

template <class T> class method_traits;
template <class T, class Ret, class... Arg> class method_traits<Ret(T::*)(Arg...)> {
public:
    using type = Arg; // this does not work
};

template <class T> using argument_types = typename method_traits<T>::type;

template <class T> class Node {
    T t;
public:
    Node(Input<argument_types<decltype(&T::process)>>... inputs) { // how do I make this work?
        ...
    }
};
Run Code Online (Sandbox Code Playgroud)

构造函数Node<T>的参数取决于方法的参数T::process.因此,如果类型T具有process签名方法,float process(float a, int b)则构造函数的签名Node<T>应如下所示:Node(Input<float> a, Input<int> b).

如何从 …

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

10
推荐指数
1
解决办法
1030
查看次数

是否可以static_assert确定lambda不是通用的?

我实现了一个Visit函数(在变体上),该函数检查变体中当前活动的类型是否与函数签名(更确切地说是第一个参数)匹配。基于这个不错的答案。例如

#include <variant>
#include <string>
#include <iostream>

template<typename Ret, typename Arg, typename... Rest>
Arg first_argument_helper(Ret(*) (Arg, Rest...));

template<typename Ret, typename F, typename Arg, typename... Rest>
Arg first_argument_helper(Ret(F::*) (Arg, Rest...));

template<typename Ret, typename F, typename Arg, typename... Rest>
Arg first_argument_helper(Ret(F::*) (Arg, Rest...) const);

template <typename F>
decltype(first_argument_helper(&F::operator())) first_argument_helper(F);

template <typename T>
using first_argument = decltype(first_argument_helper(std::declval<T>()));

std::variant<int, std::string> data="abc";
template <typename V>
void Visit(V v){
using Arg1 = typename std::remove_const_t<std::remove_reference_t<first_argument<V>>>;//... TMP magic to get 1st argument of visitor + remove …
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming variadic-templates generic-lambda c++17

10
推荐指数
1
解决办法
867
查看次数

模板专业化与别名模板推导的区别

在以下情况下,我难以理解推论的工作原理:

template<class Category, Category code>
struct AImpl
{ };

template<class Category, Category code>
struct AHelper
{
    using type = AImpl<Category, code>;
};

template<class Category, Category code>
using A = typename AHelper<Category, code>::type;

template<int code>
void doSomething(A<int, code> object)
{
}
Run Code Online (Sandbox Code Playgroud)

以下是测试代码:

A<int, 5> a1;
doSomething(a1); // This does not compile
doSomething<5>(a1); // This compiles
Run Code Online (Sandbox Code Playgroud)

为什么在这种情况下不推导a1?

如果改用以下方式修改A:

template<class Category, Category code>
struct A
{ };
Run Code Online (Sandbox Code Playgroud)

两者都可以。有人知道为什么吗?

[edit]与混合别名和模板专业化相关的问题

c++ templates template-meta-programming c++11 template-argument-deduction

10
推荐指数
1
解决办法
277
查看次数

std :: tuple_cat,但仅包含唯一元素

我需要一个constexpr非常类似于的函数std::tuple_cat,但是与其将所有元素合并为一个元组,而不必将所有元素合并到一个元组中,而是仅在尚未添加该类型的情况下,才需要添加该元素。

将谓词传递进来std::tuple_cat会很好,但是不存在这样的API(令我非常沮丧)。我已经看到了几种使用类型特征来查找合并类型的方法,但我还没有完全理解这些方法,但是没有任何形式的constexpr函数。我不确定如何将所有内容放在一起,尽管我确定可以做到。

像这样:

std::tuple<int, short, char> First;
std::tuple<short, float> Second;
std::tuple<int, double, short> Third;

std::tuple<int, short, char, float, double> Result = tuple_cat_unique(First,Second,Third);
Run Code Online (Sandbox Code Playgroud)

c++ templates tuples template-meta-programming c++17

10
推荐指数
1
解决办法
311
查看次数