【发布时间】:2019-08-03 02:11:04
【问题描述】:
在下面的代码中,我试图通过检查容器 C 是否具有成员 value_type 来确定容器内元素的类型。如果为真,我将类型设置为“value_type”。然而,即使一个类型没有成员 value_type 并且不是容器,当传递时,编译器似乎将 HasMemberT_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>
为什么设置为真?
谢谢。
【问题讨论】:
-
ElementType无条件使用ElementTypeT<T>::Type,您必须确定在传递非容器时应该是什么类型。例如对于printType<classic>();,应该打印什么? -
当
classic被传递给它时,printType应该做什么? -
我希望它打印“Char”。我可以在部分专业化的 ElementTypeT
中写 using Type = T;以便选择char吗?或者它会失败 SFINAE 技术?
标签: c++ templates sfinae void-t