嵌套成员类型识别
Nested member type recognition
今天,我试图对某个类是否具有嵌套类型reverse_iterator
执行类型切换。我找到了这些一些可行的解决方案,如下所示:
template<typename T>
struct is_reverse_iterable
{
using yes = uint8_t;
using no = uint16_t;
template<typename U>
static yes& test(typename U::reverse_iterator*);
template<typename>
static no& test(...);
static constexpr bool value = sizeof(test<T>(0)) == sizeof(yes);
};
如果我只是从 main 检查条件,这个类工作得很好,但是,我也写了那个小函数,这会导致一些问题。
template<typename T>
void foo(T&& iter)
{
std::cout << typeid(T).name() << std::endl;
std::cout << is_reverse_iterable<T>::value << std::endl;
}
这是导致我一些问题的主要因素:
int main()
{
using namespace std;
vector<int> v;
cout << typeid(decltype(v)).name() << endl;
cout << is_reverse_iterable<decltype(v)>::value << endl;
foo(v);
return 0;
}
由于std::vector<int>
包含嵌套类型名称reverse_iterator
,人们会认为 - 或者至少,我会认为 - 无论我在哪里放置它,is_reverse_iterable<vector<int>>::value
都会返回true。但事实并非如此。这是上述主要内容的结果:
St6vectorIiSaIiEE
1
St6vectorIiSaIiEE
0
当从main调用时,结构is_reverse_iterable
识别vector<int>
中reverse_iterator
的名称,但是当从foo
调用时,它没有这样做。实际上,我不知道为什么,我希望有人向我解释问题所在:)
PS:我使用 MinGW g++ 4.7.1 进行编译,选项 -std=c++11。
问题是当你调用foo(v)
时,可以推断出T
是std::vector<int>&
类型(左值引用),所以typename T::reverse_iterator
不会编译。您可以自己轻松检查:
template<typename T>
void foo(T&& iter)
{
std::cout << typeid(T).name() << std::endl;
std::cout << is_reverse_iterable<T>::value << std::endl;
typename T::reverse_iterator t; // <-- add this line to see what's wrong
}
收益 率:
3.cpp: In instantiation of ‘void foo(T&&) [with T = std::vector<int>&]’:
3.cpp:40:10: required from here
3.cpp:27:34: error: ‘std::vector<int>&’ is not a class, struct, or union type
解决方案很简单:在启动SFINAE之前删除引用,例如
static constexpr bool value = sizeof(test<typename std::decay<T>::type>(0))
== sizeof(yes);
相关文章:
- std::visit无法识别类型
- 我有两个类需要在同一 cpp 文件中相互引用,但第一个类无法识别第二个类类型的对象
- 我的头文件 DNode 中的我的数据类型未被识别为数据类型
- 无法在VSCode中设置C++调试;无法识别调试类型
- C++ 编译错误:gnu_printf是无法识别的格式函数类型
- C++将 wwn 字符串转换为识别为十六进制的数据类型
- 编写完整专业化以识别void类型的问题
- 无法识别协变返回类型
- 我该如何允许类型的对象非专业化并在不使用指针的情况下识别何时是这种情况
- 为什么模板<类型名...>不能通过模板<模板类型名>识别为可实例化<typename>?
- CGAL 无法识别类型
- 为什么我的Visual Studio 2017编译器无法识别C++17类型推导指南
- 当例外处理时,类型识别如何工作
- 无法识别初始化类型
- 从基类识别派生的类类型
- ActiveMQCPP - 识别测量类型
- 运算符 + 无法识别类型
- 如何在增强融合向量中识别类型
- 可识别类型转换的数字文字
- 在C++中以通用的可移植方式识别类型