簡體   English   中英

使用SFINAE和void_t確定容器內元素的類型

[英]Using SFINAE and void_t to determine type of elements inside a container

在下面的代碼中,我試圖通過檢查容器C是否具有成員value_type來確定容器內元素的類型。 如果為true,則將類型設置為“ value_type”。 但是,即使當類型沒有成員value_type且不是容器時,通過時,編譯器似乎HasMemberT_value_typeHasMemberT_value_type的第二個參數設置為True,即使它給出錯誤。

template<typename...>
using void_t = void;

template<typename T, typename = void_t<>>
struct HasMemberT_value_type : std::false_type
{
};

template<typename T>
struct HasMemberT_value_type<T, void_t<typename T::value_type>> : std::true_type
{
};

template<typename T, bool = HasMemberT_value_type<T>::value>
struct ElementTypeT
{
    using Type = typename T::value_type;
};

template<typename T>
struct ElementTypeT<T, false>
{
};

template<typename T>
using ElementType = typename ElementTypeT<T>::Type;

template<typename T>
void printType(T const& c)
{
    std::cout << "Container of " << typeid(ElementType<T>).name() << " elements.\n";
}

int main()
{                                           
    std::array<char, 5> arr;
    char classic[] = {'a', 'b', 'c', 'd'};
                                            //GNU Compiler:
    printType<arr>();                       //Container of c elements.
    printType<classic>();                   //ERROR : "In instantiation of ‘struct ElementTypeT<char [4], true>’: ... error: ‘char [4]’ is not a
                                            //         class, struct, or union type
                                            //         using Type = typename T::value_type;"

}

In instantiation of 'struct ElementTypeT<char [4], true>

為什么將其設置為true?

謝謝。

printType<arr>()printType<classic>()無法編譯。 它應該是printType(arr)printType(classic)

另一個問題是ElementTypeT<T, true>具有Type成員,而ElementTypeT<T, false>沒有。 因此,當您using ElementType = typename ElementTypeT<T>::Type並在執行printType(classic)時訪問它時,它將失敗。

要解決此問題,請修改特殊化,以便可以推導數組:

template<typename T, std::size_t I>
struct ElementTypeT<T[I], false>
{
    using Type=T;
};

不知道為什么在您的代碼中實例化ElementTypeT<char [4], true> 當我運行它時,對我來說是false的。

這是使用函數重載和SFINAE進行此操作的更簡單方法:

template<class T>
typename std::decay_t<T>::value_type get_value_type( T&& );

template<class R, std::size_t I>
R get_value_type( R(&)[I] );

template<class T>
void printType(T const& c) {
    std::cout << "Container of " << typeid(get_value_type(c)).name() << " elements.\n";
}

暫無
暫無

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

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