c++ - 冲突的不匹配标签与标准库一起编译,但不以其他方式编译

标签 c++ c++11 templates tuples

我在看如何std::tuple_size在我系统的标准库中定义。我有一个 Mac OS,编译器版本是 Apple LLVM version 8.1.0 (clang-802.0.42) .标准库位于 InstalledDirg++ --version 输出的位置

鉴于以下代码无法编译(因为 clang 不喜欢将之前定义为 struct 的东西特化/重新声明为 class,反之亦然)

#include <iostream>
#include <utility>
#include <array>
#include <tuple>
#include <type_traits>

using std::cout;
using std::endl;

template <class T>
class Something;
template <class One, class Two>
struct Something<std::pair<One, Two>>;
template <class One, class Two>
class Something<std::pair<One, Two>>
    : public std::integral_constant<int, 2> {};

int main() {
  cout << std::tuple_size<std::array<int, 2>>::value << endl;
  cout << std::tuple_size<std::tuple<int, int>>::value << endl;
  cout << std::tuple_size<std::pair<int, int>>::value << endl;
}

出现以下错误

error: struct template 'Something' was previously declared as a class template [-Werror,-Wmismatched-tags]
struct Something<std::pair<One, Two>>;
^
test.cpp:49:7: note: previous use is here
class Something;

我在标准库头<array>中看到了如下代码(后面将tuple_size 专门定义为class)

template <class T> class tuple_size;
template <size_t I, class T> class tuple_element;
template <class T1, class T2> struct tuple_size<pair<T1, T2> >;

在删除 Something 的定义和声明后,在上述代码中使用时如何编译? ?上面的代码不应该引发关于 tuple_size 的警告吗?被定义或声明两次为 class另一个是 struct

最佳答案

Given that the following code does not compile (because clang does not like specializing/re-declaring something as a struct that was previously defined as a class and vice versa)

clang 没问题。

with the following error

error: struct template 'Something' was previously declared as a class template [-Werror,-Wmismatched-tags]

这表明 a) 您启用了默认情况下未启用的警告,即 -Wmismatched-tags,并且 b) 您请求将警告视为错误。

存在此警告是为了与其他编译器兼容。 C++ 可以处理不匹配的标签,所有符合规范的实现也是如此,clang 也是如此。除非您有充分的理由,否则不应启用此警告。

警告通常不会影响系统头文件,即使是本应被视为错误的警告,这就是它在那里工作的原因,但您自己的代码不是系统头文件,不是也不应该被授予相同的权限异常(exception)情况。

关于c++ - 冲突的不匹配标签与标准库一起编译,但不以其他方式编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45535789/

相关文章:

c++ - 状态机实现中type_index的使用、销毁、同步

c++ - C++ 标准中的 move 概念

c++ - 在 C++ 中获取属于另一个具有多重继承的类的类的指针

c++ - 从没有奇点的矩阵中获取俯仰和滚动

c++ - 我们如何使用 STL 容器有效地存储对象? (即根据字段的值进行搜索)

c++ - C++11 中无开销的别名模板最佳替代方案的专门化

php - View 中的 CodeIgniter 助手

c++ - 模棱两可的重载运算符 C++20

c++ - MPI C 逐行发送矩阵到所有进程子进程 (MPI_COMM_SPAWN)

c++ - 改进 if/else 语句链