簡體   English   中英

std :: enable_if不編譯(無效的模板參數)

[英]std::enable_if not compiling (invalid template argument)

我正在編寫一些應接受std :: unique_ptr並在其內容上激活operator >>的代碼,如果該指針為空,則填充該指針。

我試圖通過使用SFINAE來限制不必要的調用,但是我收到了一堆關於模板參數錯誤的錯誤消息。

編碼:

#include "serializable.h"

template <class Archive, typename T>
Archive &operator>>( Archive &in, std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, T>::type> &ptr )
{
    if ( !ptr )
        ptr.swap( Serializable::construct_from_stream( in ) ); // Constructs a Serializable derivative.

    in >> *ptr;
    return in;
}

錯誤:

// 1
error: template argument 1 is invalid
 Archive &operator>>( Archive &in, std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, T>::type> &ptr )
                                                                                                                                     ^
// 2
error: template argument 2 is invalid

// 3
error: expected '::' before '&' token
 Archive &operator>>( Archive &in, std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, T>::type> &ptr )
                                                                                                                                       ^
// 4
error: expected identifier before '&' token

// 5
error: request for member 'swap' in 'ptr', which is of non-class type 'int'
         ptr.swap( Serializable::construct_from_stream( in ) );
             ^
// 6
error: type/value mismatch at argument 1 in template parameter list for 'template<bool <anonymous>, class _Tp> struct std::enable_if'
     std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, Serializable>::type>
                                                                                                           ^
// 7
error: 'Serializable' has not been declared
     ptr.swap( Serializable::construct_from_stream( in ) );
               ^
  • 這里的代碼有什么問題?
  • 有沒有更干凈的方式寫這個? (除了明顯的“ using std :: unique_ptr”之類的東西。)

“ enable_if_t”不起作用。 但是我認為這只是我做錯了什么的擴展,甚至使enable_if最初都不起作用。

我可以說是很不對勁,因為我還收到一條關於將operator *應用於int的錯誤消息……這根本不應該放進內部(如果SFINAE正確實現)!

這里的另一個有趣的問題是,即使編譯器位於其上方,編譯器也無法識別Serializable。如果答案不重要,我將單獨對其進行查找。

我正在QtCreator 3.4.2 / Qt 5.5.0上使用MinGW 4.9.2 x32進行編譯。

謝謝。

編輯:請不要建議只創建一個像這樣的函數:

Archive &operator>>( Archive &in, std::unique_ptr<Serializable> &ptr)...

我必須知道發送給此函數的對象的實際類型,並且不能依賴多態性。

移除typename之前std::is_base_of<Serializable, T>::value (因為std:is_base_of<...>::value不是一個類型)並移動enable_if部出來的參數類型(否則T不會可推論的)。

template <class Archive, typename T>
typename std::enable_if<
    std::is_base_of<Serializable, T>::value,
    Archive &
>::type
  operator>>( Archive &in, std::unique_ptr<T> &ptr )

進行SFINAE的最佳方法和較不麻煩的一種方法是使用非類型模板參數:

template <class Archive, typename T,
    std::enable_if_t<std::is_base_of<Serializable, T>::value, int> = 0
>
Archive &operator>>( Archive &in, std::unique_ptr<T>& ptr)
{
    // ...
}

如果要縮短它:

template<typename Cond>
using my_enable = std::enable_if_t<Cond::value, int>;

template<typename T>
using is_serializable = std::is_base_of<Serializable, T>;

template <class Archive, typename T, my_enable<is_serializable<T>> = 0>
Archive &operator>>( Archive &in, std::unique_ptr<T>& ptr)
{
    // ...
}

它應該減少干擾,並減少類型推導的問題。

暫無
暫無

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

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