在尝试实现依赖于可变参数模板的一些事情时,我偶然发现了一些我无法解释的事情.我将问题归结为以下代码片段:
template <typename ... Args>
struct A {};
template <template <typename...> class Z, typename T>
struct test;
template <template <typename...> class Z, typename T>
struct test<Z, Z<T>> {
static void foo() {
std::cout << "I'm more specialized than the variadic spec, hehe!" << std::endl;
}
};
template <template <typename...> class Z, typename T, typename ... Args>
struct test<Z, Z<T, Args...>> {
static void foo() {
std::cout << "I'm variadic!" << std::endl;
}
};
int main() {
test<A, A<int>>::foo();
}
Run Code Online (Sandbox Code Playgroud)
在gcc下,它会产生错误,因为它在尝试实例化时认为两个特化都是同样专业的 …
c++ template-specialization language-lawyer variadic-templates c++11
我目前正在为Linux内核构建一个模块.我的工作版本是3.8-rc3 +.我的工作引导我实现一些ioctl()命令.如您所知,我的命令应该返回一个适当的错误代码来描述执行过程中出错的地方.这看起来很简单,但我有一个用例,我无法弄清楚应该返回哪个错误代码.
基本上,我希望用户能够为给定设备设置加密密钥.我的模块将密钥存储在RB树中,由设备唯一标识符(基本int)索引.如果"目标"设备已经在树中具有条目,则应该更新该条目,否则,模块仅使用所请求的加密密钥将新分配的条目添加到该设备的树.也就是说,尝试设置密钥时会发生多种情况:
EBUSY错误.ENOMEM错误.dying标志来表示这一点):内部我当前使用EPERM错误代码,因为调用者没有"权限"来修改条目,因为它被销毁.正如我所说,对于后一种情况,我使用EPERM错误代码,但我感觉这是错误的,我不知道我应该为此目的使用哪个错误代码.欢迎任何建议!
我还指定了linux标签,因为它ioctl()可以在用户空间应用程序中使用.
编辑:阅读完评论和答案后,我想我会这样做:
ESHUTDOWN将返回.EACCES将被使用.我目前正在开发自己的Suffix Tree实现(使用C++,但问题仍然是语言不可知).我研究了来自Ukkonen的原始论文.这篇文章很清楚,所以我开始研究我的实现并试图解决广义后缀树的问题.
在树中,使用一对整数表示从节点到另一个节点的每个子串.虽然这对于常规后缀树来说很简单,但是当多个字符串在同一个树中共存时(这将成为广义后缀树)会出现问题.实际上,现在这样的一对还不够,我们需要另一个变量来说明我们正在使用哪个参考字符串.
一个简单的例子.考虑字符串coconut:
nut将是(4,6).troublemaker在树中添加,(4,6)现在可以是:
nut 如果我们引用第一个字符串.ble 如果我们引用第二个字符串.为了解决这个问题,我想添加一个表示字符串的id:
// A pair of int is a substring (regular tree)
typedef std::pair<int,int> substring;
// We need to bind a substring to its reference string:
typedef std::pair<int, substring> mapped_substring;
Run Code Online (Sandbox Code Playgroud)
我目前面临的问题如下:
我得到一个查询,在树中添加一个字符串.在算法期间,我可能必须检查与其他已注册字符串相关的现有转换,表示为三元组(参考字符串id,k,p).一些更新操作基于子字符串索引,如何在这种条件下执行它们?
注意:这个问题与语言无关,所以我没有包含c ++ -tag,尽管显示了一些小片段.
给定一个std::tuple样对象(即,具有所定义tuple_size和get语义)和一元函子对象ftor,我想能够调用ftor所述的各元件上tuple样的对象.
如果我忽略返回值,我知道int数组技巧:
namespace details {
template <typename Ftor, typename Tuple, size_t... Is>
void apply_unary(Ftor&& ftor, Tuple&& tuple, std::index_sequence<Is...>) {
using std::get;
int arr[] = { (ftor(get<Is>(std::forward<Tuple>(tuple))), void(), 0)... };
}
} // namespace details
template <typename Ftor, typename Tuple>
void apply_unary(Ftor&& ftor, Tuple&& tuple) {
details::apply_unary(std::forward<Ftor>(ftor),
std::forward<Tuple>(tuple),
std::make_index_sequence<std::tuple_size<Tuple>::value> {});
}
Run Code Online (Sandbox Code Playgroud)
如果我想要返回值,我可以用int []调用替换该技巧, std::make_tuple然后返回.如果没有对该ftor对象的调用具有void返回值,那将是有效的...
因此我的问题是:考虑到我想得到调用的结果,我该如何处理可能返回的调用void?
唯一的要求是我应该将结果作为元组得出,并且能够告诉哪个调用导致所述结果的哪个元素元组.
我正在尝试构建一个最小堆.我已经完成了插入,删除,交换,上堆,下堆,它正常工作.
但是,我正在尝试为Min-Heapify编写一个方法.
这是我的输入:{20,14,9,6,4,5,1}
我预期的输出将是最小堆:{1,5,4,20,9,6,14}但我得到的是:{14,6,9,20,4,5,1}这是相反.
这是我的代码:
public void minHeapify(int parentIndex)
{
int left = getLeft(parentIndex);
int right = getRight(parentIndex);
int smallest = parentIndex;
if(_size >right && _heapArray[left]<_heapArray[parentIndex])
{
smallest = left;
}
if(_size>left && _heapArray[right]<_heapArray[parentIndex])
{
smallest = right;
}
if(smallest !=parentIndex)
{
replace(parentIndex, smallest);
minHeapify(smallest);
}
}
Run Code Online (Sandbox Code Playgroud)
我按照这个伪代码进行MAX-Heapify
Heapify (A, i)
l ? left [i]
r ? right [i]
if l ? heap-size [A] and A[l] > A[i]
then largest ? l
else largest ? i
if r ? …Run Code Online (Sandbox Code Playgroud) 在某些情况下,我想安排一个struct timer_list适用于自定义数据的计时器 ( )。该function结构体的字段保存将被触发的实际功能,定义如下:
void (*function)(unsigned long);
Run Code Online (Sandbox Code Playgroud)
问题是我想传递一个指针而不是unsigned long. 我知道根据架构的不同,int-ptr 转换可能安全也可能不安全,但是我找不到所有架构是否都将long整数与指针对齐,所以这是我的问题(实际上是二合一):
执行 a longto void*cast是否安全?如果不是,我应该如何处理unsigned long参数以在计时器函数中获取我想要的数据指针?
考虑以下概念:
template< typename T, std::size_t Value >
concept Is_ = requires(T&&)
{
requires Value == std::remove_cvref_t< T >::value;
};
Run Code Online (Sandbox Code Playgroud)
与函数重载相关:
template< Is_< 2 > T >
void foo(T&&)
{
std::cout << "Value is 2!" << std::endl;
}
template< typename T >
void foo(T&&)
{
std::cout << "Either no value or it isn't 2!" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
最后,我们来玩一下上面的函数:
foo(std::integral_constant< std::size_t, 2 >{}); // Choose the constrained overload
foo(std::tuple{}) // Choose the generic impl
Run Code Online (Sandbox Code Playgroud)
现在,如果我定义以下辅助变量模板:
template< typename T >
inline constexpr auto …Run Code Online (Sandbox Code Playgroud) 我目前正在为搜索树等经典数据结构编写实现.我从B +树开始.
涉及的课程如下:
template <typename Key, typename Record>
class BPlusNode {
/* ... */
}
template <typename Key, typename Record>
class BPlusINode : public BPlusNode<Key, Record> {
/* ... */
}
template <typename Key, typename Record>
class BPlusLeaf : public BPlusNode<Key, Record> {
/* ... */
}
template <typename Key, typename Record>
class BPlusTree {
/* ... */
private:
BPlusNode<Key, Record> *root;
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
我正在为我的树编写复制构造函数.它有点复杂,因为它涉及原始树上的BFS搜索,逐个复制每个节点(并相应地编辑子节点和父节点).在复制过程中的某个时刻可能发生内存分配失败(或其他任何错误).因此,我必须抛出异常来表示对象创建失败.但是我创建的所有节点会发生什么?它们会被自动销毁还是我必须清理这些烂摊子?
编辑:关于复制构造函数的一些精度
template <typename Key, typename Record>
BPlusTree<Key, Record>::BPlusTree(BPlusTree<Key, Record> &tree) …Run Code Online (Sandbox Code Playgroud) c++ ×4
algorithm ×2
c ×2
linux-kernel ×2
c++-concepts ×1
c++11 ×1
c++14 ×1
c++20 ×1
constructor ×1
heap ×1
java ×1
linux ×1
min-heap ×1
oop ×1
pointers ×1
suffix-tree ×1
templates ×1
tuples ×1