[英]Could I have an explanation of a few lines in the following code?
I would like to understand how the following code works.我想了解以下代码的工作原理。 It can basically be used to sort of "Debug" C++ containers, but I'm having some trouble understanding lines 3, 4, 12 and 13 and what they do.
它基本上可以用于对 C++ 容器进行排序,但是我在理解第 3、4、12 和 13 行以及它们的作用时遇到了一些麻烦。 It would be great if I could receive a brief explanation.
如果我能得到一个简短的解释就太好了。 Thanks.
谢谢。
template <typename T> class range { public: T begin, end; };
template <typename T> range <T> make_range (const T& b, const T& e) { return range <T> {b, e}; }
template <typename T> auto dec (T* x) -> decltype(std::cerr << *x, 0); // 3
template <typename T> char dec (...); // 4
class view {
private:
std::ostream& stream;
public:
view (std::ostream&);
~view ();
#ifdef Z_LOCAL
template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type operator << (const T&); // 12
template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type operator << (const T&); // 13
template <typename T> view& operator << (const range <T>&);
template <typename A, typename B> view& operator << (const std::pair <A, B>&);
#else
template <typename T> view& operator << (const T&);
#endif
};
view::view (std::ostream& os = std::cerr) : stream (os) { }
view::~view () { stream << std::endl; }
#ifdef Z_LOCAL
template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type view::operator << (const T& t)
{ stream << std::boolalpha << t; return *this; }
template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type view::operator << (const T& t)
{ return *this << make_range(begin(t), end(t)); }
template <typename T> view& view::operator << (const range <T>& r)
{ stream << "["; for (auto i = r.begin, j = i; i != r.end; ++i) *this << *i << (++j == r.end ? "]" : ", "); return *this; }
template <typename A, typename B> view& view::operator << (const std::pair <A, B>& p)
{ stream << '(' << p.first << ", " << p.second << ')'; return *this; }
#else
template <typename T> view& view::operator << (const T&)
{ return *this; }
#endif
#define print(x) " [" << #x << ": " << x << "] "
view debug (std::cerr);
The following declarations are using a technique that relies on SFINAE (substitution failure is not an error):以下声明使用了一种依赖于 SFINAE 的技术(替换失败不是错误):
// #3 : works only if (std::cerr << *x) works
template <typename T> auto dec (T* x) -> decltype(std::cerr << *x, 0);
// #4 : works for everything, but only if #3 fails
template <typename T> char dec (...);
Consider some type T
such as double
.考虑一些类型
T
例如double
。 Then the following code, where x
is a double*
:然后是以下代码,其中
x
是double*
:
std::cerr << *x;
would compile just fine, which means that this code:会编译得很好,这意味着这段代码:
decltype(std::cerr << *x, 0);
is well formed, and evaluates to int
.格式良好,计算结果为
int
。 The compiler will then pick #3
when T
is a type that can be used like this.当
T
是可以像这样使用的类型时,编译器将选择#3
。
On the other hand, if T
is something like a vector<double>
, then the decltype
is not well formed (since you can't stream a vector
to cerr
), and so the compiler has no choice but to pick #4
.另一方面,如果
T
类似于vector<double>
,则decltype
的格式不正确(因为您无法将vector
流式传输到cerr
),因此编译器别无选择,只能选择#4
。
The above declarations are simply helpers that are used in #12
and #13
.上面的声明只是在
#12
和#13
中使用的助手。 If T
is a type that works for #3
, then dec
has a return type of int
, and the following overload is matched:如果
T
是适用于#3
的类型,则dec
的返回类型为int
,并且匹配以下重载:
// #12
template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type operator << (const T&);
because sizeof dec <T>
would not be 1.因为
sizeof dec <T>
不会是 1。
If T
works for #4
(because it didn't work for #3
), then dec
has a return type of int
, and the following overload #13
is matched:如果
T
适用于#4
(因为它不适用于#3
),则dec
的返回类型为int
,并且匹配以下重载#13
:
// #13
template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type operator << (const T&);
because sizeof dec <T>
would be exactly 1 (the size of a char
).因为
sizeof dec <T>
正好是 1(一个char
的大小)。
Note that the real difference is how #12
and #13
are defined .请注意,真正的区别在于
#12
和#13
的定义方式。 If you see the definitions, they handle the cases where T
is streamable or not appropriately.如果您看到定义,它们会处理
T
可流式传输或不适当的情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.