在此回复中:
https://stackoverflow.com/a/14382318/1676605
这个程序是:
std::vector<int> vi{ 0, 2, 4 };
std::vector<std::string> vs{ "1", "3", "5", "7" };
for (auto i : redi::zip(vi, vs))
std::cout << i.get<0>() << ' ' << i.get<1>() << ' ';
我不知道auto i
的类型是什么,使得重用专业知识和从示例中学习变得更加困难。以下是将auto i
更改为char i
的内容
In function ‘int main()’:|
/data/cbworkspace/TestZip/TestZip.cpp|14|error: cannot convert ‘boost::iterator_facade<boost::zip_iterator<boost::tuples::tuple<__gnu_cxx::__normal_iterator<int*, std::vector<int> >, __gnu_cxx::__normal_iterator<int*, std::vector<int> > > >, boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, boost::random_access_traversal_tag, boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >, long int>::reference {aka boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >}’ to ‘char’ in initialization|
/data/cbworkspace/TestZip/TestZip.cpp|14|warning: unused variable ‘i’ [-Wunused-variable]|
||=== Build finished: 1 errors, 1 warnings (0 minutes, 0 seconds) ===|
尝试从中找出类型。
有没有办法弄清楚{+ 1}} 的变量在C ++ 11中的类型?为了更清楚,我有auto
这样的:
struct
答案 0 :(得分:14)
尝试将auto更改为char并阅读错误消息。
答案 1 :(得分:9)
为什么要将该类型放在结构中?它并不是真的被设计成这样使用(我应该知道,我写了它!)但是如果有必要,你可以使用decltype
和std::declval
来确定类型(如果我仍然会给出正确的答案)改变redi::zip
)
struct EventData
{
// type returned by redi::zip
typedef decltype(redi::zip(std::declval<V1>(), std::declval<V2>())) zipper_type;
// type referred to by zipper_type::iterator
typedef std::iterator_traits<zipper_type::iterator>::value_type zipped_type;
zipper_type m_zipper;
};
N.B。为什么要为typedef
创建struct
?这是C ++而不是C,停止它。
我不知道auto i的类型是什么,使得重用专业知识和从示例中学习变得更加困难。
习惯它。你知道std::bind
返回的类型吗?你知道std::mem_fn
返回的类型吗?你知道lambda表达式创建的类型吗?不,您不需要知道,您需要知道的是它具有哪些属性以及您可以用它做什么,而不是它的名称或它包含的类型。
答案 2 :(得分:8)
你找到了吗
for (boost::iterator_facade<
boost::zip_iterator<
boost::tuples::tuple<std::vector<int>::iterator,
std::vector<int>::iterator>
>,
boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >,
boost::random_access_traversal_tag,
boost::tuples::cons<int&, boost::tuples::cons<int&, boost::tuples::null_type> >,
long int
>::reference i : redi::zip(vi, vs))
std::cout << i.get<0>() << ' ' << i.get<1>() << ' ';
更容易理解?
答案 3 :(得分:3)
找出redi::zip()
返回的最佳方法是查看redi::zip()
返回的内容。 =)
我的IDE让我通过按住Ctrl并单击zip()
直接跳到它。你们不提供类似的功能吗?
我甚至可以将鼠标悬停在zip()
循环中的for()
上,并获得一个提供函数签名的工具提示 - 包括返回类型。
无论如何你都需要查看它来键入你手动替换'auto'的内容,并且auto会提供很大的好处,它可以让你声明那些不可能声明的类型(比如lambda返回,除非做复杂的东西,如decltype,它有你不喜欢 auto 的相同缺陷。
当IDE更多地支持C ++ 11时,你的intellisense会更好地发挥作用,而且类型更清晰。我确信在一年或更短的时间内,大多数最新的IDE会在悬停时告诉你 auto 的真实类型。
auto 的收益远远超过了损失,但是,有一个很小的损失会在IDE支持良好的情况下变得更加微弱。几乎所有事情都有利有弊。
答案 4 :(得分:2)
我不同意你的断言,即不知道i
的类型“使得重用专业知识并从示例中学习更难”。 i
的类型是“zip
返回的内容”。为什么这还不够?
答案 5 :(得分:1)
除了其他答案,我还想使用<boost/type_index.hpp>
:
int main()
{
using namespace std;
using namespace boost::typeindex;
auto p = std::make_pair(1, 2);
cout << type_id_with_cvr<decltype(p)>().pretty_name();
}
哪个输出:
std::pair<int, int>
您还可以使用typeid()
中的<typeinfo>
:
auto p = std::make_pair(1, 2);
cout << typeid(p).name() << '\n';
输出不像第一个例子那样容易理解,但仍然是:
St4pairIiiE
答案 6 :(得分:0)
Windows:Visual Studio上的内置调试器将为您提供类型信息。
Linux:在exe中断作用域中的变量时,调试gdb中的代码并提交ptype <varname>
。输出示例-在这种情况下,我可以将auto
替换为vector<uint8_t>::const_iterator
,但这并不是特别明显:
type = class __gnu_cxx::__normal_iterator
<unsigned char const*,
std::vector<unsigned char,
std::allocator<unsigned char>
>
>
[with _Iterator = const unsigned char *,
_Container = std::vector<unsigned char, std::allocator<unsigned char> >]
{
protected:
_Iterator _M_current;
public:
__normal_iterator(void);
__normal_iterator(const unsigned char * const&);
reference operator*(void) const;
_Iterator operator->(void) const;
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator++(void);
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator++(int);
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator--(void);
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator--(int);
reference operator[](difference_type) const;
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator+=(difference_type);
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator+(difference_type) const;
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> & operator-=(difference_type);
__gnu_cxx::__normal_iterator<unsigned char const*, _Container> operator-(difference_type) const;
const unsigned char * const& base(void) const;
void __normal_iterator<unsigned char*>(const
__gnu_cxx::__normal_iterator<unsigned char*, _Container> &);
typedef std::iterator_traits<unsigned char const*>::reference reference;
typedef _Iterator pointer;
typedef std::iterator_traits<unsigned char const*>::difference_type difference_type;
typedef std::iterator_traits<unsigned char const*>::iterator_category iterator_category;
}
答案 7 :(得分:0)
答案
“在编译时如何确定'auto'变量的实际类型 ”
尝试编译如下内容:
auto foo = function_that_returns_unknown_type() // "what type could foo be?"
int a = foo;
编译器错误消息将告诉您“类型XXX
(无论是哪种类型)都不能转换为int
”。在那里输入文字