在下面的示例中,Abstract
是一个类模板,其第一个参数是一个类型,第二个参数是另一个模板,它带有一个bool以及任意数量的args.
template<bool,typename>
struct Default;
template< typename T = void,
template<bool,typename ...> class = Default>
struct Abstract;
template<typename T>
struct Abstract<T>
{};
template<typename T, template<bool> class C>
struct Abstract<T,C> : Abstract<T>
{};
int main()
{}
Run Code Online (Sandbox Code Playgroud)
Clang和C++的输出如下:
Clang: http ://rextester.com/BJSW46677
错误:类模板部分特化没有专门化任何模板参数;
G ++ http://rextester.com/MDN65674
好
所以,我决定对clang友好,并在Abstract
声明中添加了第三个参数.
template< typename T = void,
template<bool,typename ...> class = Default,
typename = void >
struct Abstract;
Run Code Online (Sandbox Code Playgroud)
现在,Clang和G ++都很好.我想Clang抱怨的原因是因为专业化并没有真正专门化.但事实并非如此.它专门针对参数的数量.
接下来,我为模板模板参数添加了另一个专门化.示例如下所示:
template<bool,typename>
struct Default;
template< typename T = void,
template<bool,typename ...> class = …
Run Code Online (Sandbox Code Playgroud) 根据理论为二叉树创建节点的正确方法是什么?例如:
struct Node
{
int data;
Node *left;
Node *right;
};
Run Code Online (Sandbox Code Playgroud)
我目前面临的问题是,我从几个来源(书籍,网站,在线讲座等)有2个不同的答案。
从“算法简介”第3版,第286,287页:“除了密钥和卫星数据之外,每个节点还包含左,右和p属性,这些属性指向与其左子节点,右子节点及其节点相对应的节点。父母”。
意思是这样的:
struct Node
{
int data;
Node *parent;
Node *left;
Node *right;
};
Run Code Online (Sandbox Code Playgroud)
另一方面,我发现了几个不遵循此设计的链接,例如:
http://algs4.cs.princeton.edu/32bst/
http://math.hws.edu/eck/cs225/s03/binary_trees/
http://www.cprogramming.com/tutorial/lesson18.html
这些实现不与父代保持链接,并且从一些在线讲座中可以得知,Trees不会向后遍历(也就是看不到父代),这与本书中的概念背道而驰!
例如,在RedBlack树中,您需要查看该节点的祖父母和叔叔以确定是否重新着色和/或旋转以重新平衡树。在AVL树中,您不必这样做,因为重点是子树的高度。四叉树和八叉树与您不需要父级的相同。
问题:
有人可以回答我这个问题,并提供有效的资料,解释为二进制树或任何树(B树等)设计节点的正确方法是什么?
还有向后遍历的规则是什么?我知道遍历的预排序,有序,后排序,广度优先,深度优先(预排序)和其他AI启发式算法。
确实不允许您在一棵树中向后移动,即从孩子到父母吗?如果是这样,那本书为什么会建议到父节点的链接?
以下代码在GCC(4.9.3)和VC++(19.00.23506)中编译良好,但在Clang(3.7.0)中给出了这些错误.
错误:constexpr函数的返回类型'Foo'不是文字类型
注意:'Foo'不是字面值,因为它不是聚合,除了复制或移动构造函数之外没有constexpr构造函数
码:
#include <iostream>
#include <vector>
struct Foo
{
std::vector<int> m_vec;
Foo(const int *foo, std::size_t size=0):m_vec(foo, foo+size)
{;}
//Foo(const std::initializer_list<int> &init):m_vec{init}
//{;}
};
template <std::size_t N>
constexpr Foo make_fooArray(const int (&a)[N]) noexcept
{
return {a,N};
}
int main()
{
Foo f{ make_fooArray({1,2,3}) };
for (auto i : f.m_vec)
std::cout<< i <<" ";
std::cout<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在rextester上运行的代码:
你能否澄清这是一个编译器错误还是我错过了什么?C++ 11标准说什么?
这是另一个案例,它在GCC和VC中编译但在Clang中不编译.
#include <iostream>
template <typename T, std::size_t N>
constexpr std::size_t sizeOf_fooArray(const T (&)[N]) noexcept
{
return N;
}
int …
Run Code Online (Sandbox Code Playgroud) 下面的前向声明,在类模板特化阶段,是合法的 C++ 代码吗?
template<typename>
struct Basic
{};
template<>
struct Basic<struct Foo> //<-- Fwd declaration?
{};
struct Foo
{
Basic<Foo> m_a;
};
int main()
{
Foo test;
}
Run Code Online (Sandbox Code Playgroud)
它确实可以编译,但我不确定它是否合法
我认为指定的初始化程序在C++中已经停止,并且仅在C中工作.但是,我遇到了一个简单的例子,它使用clang ++进行编译和工作.
int main()
{
int a[6] = { [4] = 29, [2] = 15 };
}
Run Code Online (Sandbox Code Playgroud)
g ++:https://rextester.com/AXIZ79197(错误)
clang ++:https://rextester.com/UYVHHP56966(作品)
vc ++:https://rextester.com/UCBEU10658(错误)
g ++和vc ++都无法编译,而clang ++工作正常.值得一提的是,g ++和vc ++给出了不同的错误消息.vc ++将指定的初始值设定项与lambda表达式混淆.我想我可以将此归结为g ++是一个较旧的编译器,但我不确定.
问题: