簡體   English   中英

我可以解釋以下代碼中的幾行嗎?

[英]Could I have an explanation of a few lines in the following code?

我想了解以下代碼的工作原理。 它基本上可以用於對 C++ 容器進行排序,但是我在理解第 3、4、12 和 13 行以及它們的作用時遇到了一些麻煩。 如果我能得到一個簡短的解釋就太好了。 謝謝。

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);

以下聲明使用了一種依賴於 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 (...); 

考慮一些類型T例如double 然后是以下代碼,其中xdouble*

std::cerr << *x;

會編譯得很好,這意味着這段代碼:

decltype(std::cerr << *x, 0);

格式良好,計算結果為int T是可以像這樣使用的類型時,編譯器將選擇#3

另一方面,如果T類似於vector<double> ,則decltype的格式不正確(因為您無法將vector流式傳輸到cerr ),因此編譯器別無選擇,只能選擇#4


上面的聲明只是在#12#13中使用的助手。 如果T是適用於#3的類型,則dec的返回類型為int ,並且匹配以下重載:

// #12
template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type operator << (const T&);

因為sizeof dec <T>不會是 1。

如果T適用於#4 (因為它不適用於#3 ),則dec的返回類型為int ,並且匹配以下重載#13

// #13
template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type operator << (const T&); 

因為sizeof dec <T>正好是 1(一個char的大小)。


請注意,真正的區別在於#12#13定義方式 如果您看到定義,它們會處理T可流式傳輸或不適當的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM