小编Con*_*nos的帖子

Clang vs G ++对类模板的参数数量和模板模板参数重新声明不一致

在下面的示例中,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)

c++ templates language-lawyer c++14

7
推荐指数
1
解决办法
300
查看次数

任何BST树中的节点的正确结构是什么

根据理论为二叉树创建节点的正确方法是什么?例如:

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启发式算法。

确实不允许您在一棵树中向后移动,即从孩子到父母吗?如果是这样,那本书为什么会建议到父节点的链接?

c++ algorithm binary-search-tree

2
推荐指数
1
解决办法
862
查看次数

Clang 3.7.0抱怨类不是字面值,因为它不是聚合而且没有constexpr构造函数

以下代码在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上运行的代码:

海湾合作委员会和VC

你能否澄清这是一个编译器错误还是我错过了什么?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++ constexpr c++11 clang++ c++14

2
推荐指数
1
解决办法
473
查看次数

类模板专业化的前向声明

下面的前向声明,在类模板特化阶段,是合法的 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++ templates

2
推荐指数
1
解决办法
451
查看次数

为什么Clang决定允许在C++中使用指定的初始值设定项?

我认为指定的初始化程序在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 ++是一个较旧的编译器,但我不确定.

问题:

  1. 当g ++和vc ++没有时,为什么clang决定允许指定的初始值设定项?
  2. 这只是一个编译器错误还是有另一个原因?

c++ arrays designated-initializer

2
推荐指数
1
解决办法
535
查看次数