我想std::set用自定义比较函数创建一个.我可以将它定义为一个类operator(),但我想享受定义使用它的lambda的能力,所以我决定在具有std::setas成员的类的构造函数的初始化列表中定义lambda函数.但我无法得到lambda的类型.在我继续之前,这是一个例子:
class Foo
{
private:
std::set<int, /*???*/> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
Run Code Online (Sandbox Code Playgroud)
我在搜索后找到了两个解决方案:一个,使用std::function.只需设置比较函数类型std::function<bool (int, int)>,就像我一样传递lambda.第二个解决方案是编写一个make_set函数,就像std::make_pair.
解决方案1:
class Foo
{
private:
std::set<int, std::function<bool (int, int)> numbers;
public:
Foo () : numbers ([](int x, int y)
{
return x < y;
})
{
}
};
Run Code Online (Sandbox Code Playgroud)
解决方案2:
template <class Key, class Compare>
std::set<Key, Compare> make_set (Compare compare) …Run Code Online (Sandbox Code Playgroud) 假设我有一组unique_ptr:
std::unordered_set <std::unique_ptr <MyClass>> my_set;
Run Code Online (Sandbox Code Playgroud)
我不确定检查集合中是否存在给定指针的安全方法是什么.这样做的正常方法可能是调用my_set.find (),但我作为参数传递什么?
我从外面得到的只是一个原始指针.所以我必须从指针创建另一个unique_ptr,将它传递给find()然后release()指针,否则对象将被破坏(两次).当然,这个过程可以在一个函数中完成,因此调用者可以传递原始指针并进行转换.
这种方法安全吗?有没有更好的方法来使用一组unique_ptr?
我有一个函数,它带有一个默认值的参数.现在我还希望它采用可变数量的参数并将它们转发给其他函数.默认值的函数参数必须是最后一个,所以...我可以将该参数放在可变参数包之后,编译器会在调用函数时检测我是否提供它吗?
(假设包不包含最后一个参数的类型.如果需要,我们可以假设,因为这种类型一般不应该被称为给用户,否则它反正认为我的接口错误使用.. ..)
template <class... Args>
void func (Args&&... args, SomeSpecialType num = fromNum(5))
{
}
Run Code Online (Sandbox Code Playgroud) c++ default-value variadic-functions variadic-templates c++11
我有一个继承链,Base是基类.我希望能够编写一个继承Base和另一个Base派生类的类模板.我可以使用虚拟继承,但我发现了另一种解决方案.我想知道它是否是普通/相当/合法的类设计:
编写一个类模板,其中模板参数是从中派生的类,即它必须是Base或Base派生类.在构造函数中,我可以使用静态断言来确保用户不使用任何非法类作为模板参数.
如果它工作,我将永远不会有虚拟继承问题...问题是,它可以做到这一点.我从未在其他项目中看到它,所以我想在使用它之前确定它.
编辑:只是为了确保我不要混淆你,这里有一些代码:
class Base
{
};
class Derived : public Base
{
};
template <Class TheBase>
class MyDerived : public TheBase
{
};
Run Code Online (Sandbox Code Playgroud)
现在我可以使用Base或任何Base衍生的类,例如Derived,作为TheBase参数.
我有一个由Graph和Node类实现的有向无环图.每个节点都有一个指向childern的指针列表和一个指向父节点的指针列表.我最近添加了父母,因为有些算法要求快速访问父列表,图表很小,每个节点只有几个连接,所以没有内存问题.
子列表使用std :: shared_ptr,以便节点至少与父节点一样保留在内存中.但我不希望节点拥有其父节点,所以我使用weak_ptr作为指向父节点的指针.
但是那时算法存在问题.算法必须从weak_ptr创建一个新的shared_ptr,所以我不能直接使用operator ==,并且使用标准函数如std :: find()需要编写一个名为my_weak_ptr.lock()的lambda函数然后进行比较到某些shared_ptr.
如果我切换到shared_ptr,代码中任何可删除节点的小错误都可能导致内存泄漏.或者如果我有一个已经删除的节点的指针,代码将能够访问不应该存在的节点,因此找到一些错误可能会变得更加困难.但是,在不解除引用/删除/等方面,使用shared_ptr与weak_ptr一样安全.什么时候不应该,(因此它比原始的C++指针更好)和std :: find()可以直接使用,因为与weak_ptr不同,shared_ptr可以被解引用.
这里是否有"更好"的设计,或者这是一个特定情况的问题,具体取决于例如,如果我执行weak_ptr :: lock()的额外操作或者冒险难以发现错误,这有多重要?
我在Autoconf Archive中找到了几个有用的宏,还有一个有用的m4文件,它有助于测试Boost库的支持.Autoconf Archive由GNU托管,Boost m4帮助器作为GitHub仓库托管.我想在一个使用Autotools并由git管理的C++项目中使用它们.
显然,可以手动下载它们并插入我的项目的git仓库.但有更推荐的方法吗?
例如,通过使构建过程自动下载它们而不是手动更新它们,可以确保第三方文件是最新版本.它还有助于将源与外部文件分开,因为第三方文件实际上不是纯源代码的一部分,而是外部下载的文件.
如果这是一件好事,应该通过autogen.sh手动完成吗?或者使用automake.am?或两者兼而有之(例如在autogen.sh下载文件和在automake中测试版本+更新)?
我想将它们保存在git repo中并不是一场灾难(就像COPYING,git.mk和其他人一样),但是让构建过程从Web更新到最新版本仍然很有用.
我可以使用显式的init-list ctor来确保像{a}这样的表达式不会导致意外的隐式转换吗?而另一个想法:应该我担心呢?写作{a}不太可能是简单的错误a,但另一方面,我们通过隐式转换构建对象的代码仍然可能不清楚.
class Foo
{
explicit Foo (std::initializer_list<Bar> ilist) { /*...*/}
};
Run Code Online (Sandbox Code Playgroud) 我有一个名为Graph的C++类,它有一个算法方法for_each_node().我可以把它变成一个模板,像这样:
template <class UnaryFunction>
UnaryFunction Graph::for_each_node (UnaryFunction f)
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
或者使用std :: function,如下所示:
typedef std::function<void (Node&)> ForEachNodeFunc;
ForEachNodeFunc Graph::for_each_node (ForEachNodeFunc f)
{
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
标准算法,例如std :: for_each,使用第一种方法,而一些库,例如gtkmm(它是GTK +的C++绑定),将函数作为包含它们的对象的函数指针.
每个选项有哪些优点和缺点?我不知道该选哪个.应该影响选择的是什么:我的Graph类是一个类模板,或者算法方法或速度要求预计会使用多少个不同的函数?
std :: list的一些方法,可能还有其他STL容器,在C++ 11中添加了一个新的重载.我需要的是list :: splice().一种方法采用列表和参数,另一种采用列表&&参数.
我想知道有什么不同,我应该更喜欢哪个.
我查看了libstdc ++(GCC编译器使用的标准C++库)的实现,并在内部使用了两种情况下的list &&版本.此外,C++ 11规范没有提到这个问题.它只提供了两种方法而没有解释差异.
你不移动列表本身,并且你不移动节点(复制它们的指针似乎是将节点从一个列表移动到另一个列表的方式),那么它为什么重要呢?我只有一个想法,也许使用list &&就像对编译器的承诺,你不再需要其他列表,编译器可以保存一些操作,因为它不必保持其他列表有效...
我有一个带有模板参数T的类模板Templ,而Templ类有一个类型为T的数据成员,称为obj.我编写了一个可变参数构造函数模板,它将参数转发给obj的构造函数:
template <class T>
class Templ
{
public:
template <class... Args> explicit Templ (Args&&... args)
: obj (std::forward<Args>(args)...)
{
}
private:
T obj;
};
Run Code Online (Sandbox Code Playgroud)
现在我意识到类型T可能是一个带有init-list构造函数的类,我希望它可以通过Templ访问.所以我检查了什么std::list::emplace,std::make_shared做了什么.它们具有像我一样的可变函数,但它们没有覆盖init-list的覆盖.由于某些原因.
所以第一个问题:为什么?我的意思是,如果我使用一个带有init-list ctor的类T,然后我用std::list<T>?为什么list ::\templates没有带初始化列表的版本?也许有一个很好的理由我应该这样做...所以我想知道.
此外,无论STL做什么 - 我应该提供一个init-list ctor作为好的设计吗?我的意思是,它就像可变的ctor,对吗?允许用户选择任何类型或种类的T,带TEMPL <>使用,并且直接调用为T.定义的任何构造函数即使它是一个构造函数采取一个init-列表.
c++ ×9
c++11 ×8
stl ×3
std-function ×2
autoconf ×1
automake ×1
autotools ×1
git ×1
inheritance ×1
lambda ×1
make-shared ×1
oop ×1
shared-ptr ×1
templates ×1
unique-ptr ×1