我最近写了一个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) 让我们假设,我们有一个模板功能:
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) 我有一堆有名字的类型.(它们有更多功能,但为了讨论起见,只有名称是相关的.)这些类型及其名称是在编译时使用宏设置的:
#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)
代码在这里归结为它可能包含错误的程度,但实际上这很好用.
除了它在运行时创建然后复制相当长的字符串,这些字符串表示在编译时实际上是众所周知的类型.由于这是一个在嵌入式设备上运行的性能相当敏感的代码,我想改变这一点
我怎样才能做到这一点?
(如果这扩大了可用于此的脏技巧:foo只能通过代码创建和读取对象的foo_list名称,并且只有名称字符串应该是人类可读的.)
来自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(或者有时只是崩溃).
如何实现这样的功能?
如何检查两个参数包是否相同,忽略它们的内部顺序?
到目前为止,我只有框架(使用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
#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并使其按预期工作.
请考虑以下示例:
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
我实现了一个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
在以下情况下,我难以理解推论的工作原理:
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
我需要一个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)