我正在研究如何在我的系统上的标准库中定义std::tuple_size
。我有一台Mac OS,编译器版本为Apple LLVM version 8.1.0 (clang-802.0.42)
。标准库位于InstalledDir
g++ --version
位置
鉴于以下代码无法编译(因为clang
不喜欢将某些内容专门化/重新声明为struct
,之前已定义为class
,反之亦然)< / p>
#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
的警告?
答案 0 :(得分:2)
鉴于以下代码无法编译(因为clang不喜欢将某些内容专门化/重新声明为以前定义为类的结构,反之亦然)
clang很好。
出现以下错误
error: struct template 'Something' was previously declared as a class template [-Werror,-Wmismatched-tags]
这表明a)您启用了默认情况下未启用的警告,即-Wmismatched-tags
,以及b)您请求将警告视为错误。
此警告存在是为了与其他编译器兼容。 C ++适用于不匹配的标签,因此所有符合标准的实现,所以是clang。除非你有充分的理由,否则你不应该启用此警告。
警告通常不会影响系统头,甚至是否会被视为错误的警告,这就是它在那里工作的原因,但是你自己的代码不是系统头,并且不是也不应该被授予相同的权限异常。
答案 1 :(得分:0)
我认为<array>
编译感谢
#pragma GCC system_header
你可以在其中找到(或者,至少在我的标题版本中)。
尝试编写以下标题(“something.h”)
#ifndef _something_h_
#define _something_h_
//#pragma GCC system_header
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>>
{};
#endif /* ndef _something_h_ */
并修改主cpp文件,如下所示
#include <iostream>
#include <utility>
#include <array>
#include <tuple>
#include <type_traits>
#include "something.h"
using std::cout;
using std::endl;
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;
}
如果注释了pragma行,你应该得到同样的错误。
取消注释“something.h”中的pragma行,并且应该编译没有问题。