如何确定“自动”变量的实际类型

时间:2021-05-29 04:15:40

In this response:

在这个反应:

https://*.com/a/14382318/1676605

https://*.com/a/14382318/1676605

this program is given:

这个程序是:

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>() << ' ';

I have no idea what the type of auto i is, making it harder to reuse expertise and learn from examples. Here is what changing auto i into char i returns

我不知道I是什么类型的汽车,这使得重用专业知识和从示例中学习变得更加困难。这里是将自动i转换为char返回的值

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) ===|

Try to figure out the type from that.

试着从中找出类型。

Is there a way to figure out what the type a variable of an auto is in C++11? To be more clear, I have a struct like this:

有没有一种方法可以算出自动变量在c++ 11中的类型?更明确地说,我有这样一个结构:

struct EventData
{
    // return value from redi::zip<std::vector<PriceQuote>, std::vector<PriceQuote>> what goes here????? So REDI::Zip is zipping PriceQuote, PriceQuote of bids and asks.
};

struct PriceQuote
{
   double price;
   double size;
};

6 个解决方案

#1


8  

Why do you want to put that type in a struct? It's not really designed to be used like that (I should know, I wrote it!) but if necessary you can use decltype and std::declvalto determine the type (which will still give the right answer if I change the implementation of redi::zip)

为什么要把这个类型放到一个结构中呢?它并不是设计成这样使用的(我应该知道,我写了它!)但是如果需要,您可以使用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. why are you creating a typedef for the struct? This is C++ not C, stop it.

注意:为什么要为结构体创建类型定义?这是c++,不是C,停下来。

I have no idea what the type of auto i is, making it harder to reuse expertise and learn from examples.

我不知道我是什么类型的汽车,使它更难重用专业知识和从例子中学习。

Get used to it. Do you know the type that std::bind returns? Do you know the type that std::mem_fn returns? Do you know the type that a lambda expression creates? No, you don't need to know, all you need to know is what properties it has and what you can do with it, not what it's called or what types it contains.

要去适应它。你知道std::bind return是什么类型吗?您知道std::mem_fn返回的类型吗?你知道lambda表达式创建的类型吗?不,你不需要知道,你只需要知道它有什么属性,你可以用它做什么,而不需要知道它叫什么或包含什么类型。

#2


8  

Try to change auto into a char and read the error message.

尝试将自动转换为字符并读取错误消息。

#3


8  

Would you have found

你会发现

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>() << ' ';

easier to understand?

更容易理解?

#4


3  

The best way to figure out what redi::zip() returns is to look at what redi::zip() returns. =) My IDE lets me jump straight to it by holding Ctrl and clicking zip(). Doesn't yours offer similar features? I can even just hover over zip() in the for() loop, and get a tooltip that gives the function signature - including the return type.

找出redi::zip()返回的最佳方法是查看redi::zip()返回。我的IDE让我通过按住Ctrl并点击zip()直接跳转到它。你们的产品也有类似的特点吗?我甚至可以在for()循环中略过zip(),并得到一个提供函数签名的工具提示——包括返回类型。

You'll need to look at it anyway for typing whatever you'd manually replace 'auto' with, and auto serves the great benefit that it lets you declare types that it's impossible to otherwise declare (like lambda returns, unless doing complex things like decltype, which has the same flaw you don't like about auto).

你需要看无论如何手动输入任何你想取代“汽车”,和汽车服务大有好处,它允许您声明类型,否则无法申报(如λ的回报,除非像decltype做复杂的事情,你有相同的缺陷不喜欢汽车)。

When IDEs support C++11 more, your intellisense would kick in better, and it'll be clearer what the type is. I'm sure in a year or less, most up-to-date IDEs will tell you the auto's true type when hovered over.

当ide支持更多的c++ 11时,您的智能感知会更好地发挥作用,并且它将更清晰地显示类型。我敢肯定,在一年或更短的时间内,大多数最新的ide都能告诉您当鼠标悬停时汽车的真正类型。

The gains of auto far outweigh the losses, though, yes, there is a tiny loss that will become even tinier with good IDE support. Almost everything has pros and cons.

汽车的收益远远超过损失,但是,是的,有一个小的损失将变得更小,有良好的IDE支持。几乎每件事都有利弊。

#5


2  

I disagree with your assertion that not knowing the type of i is "making it harder to reuse expertise and learn from examples". The type of i is "that thing that zip returns". Why isn't that sufficient?

我不同意您的断言,即不知道我的类型“使重用专业知识和从示例中学习变得更加困难”。i的类型是“zip返回的那个东西”。为什么这不是足够了吗?

#6


1  

Apart from other answers, I like to use <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();
}

Which outputs:

输出:

std::pair<int, int>

You can also use typeid() from <typeinfo>:

您还可以使用 中的typeid():

auto p = std::make_pair(1, 2);
cout << typeid(p).name() << '\n';

The output is not as understandable as the first example, but still:

输出不像第一个例子那么容易理解,但仍然:

St4pairIiiE

#1


8  

Why do you want to put that type in a struct? It's not really designed to be used like that (I should know, I wrote it!) but if necessary you can use decltype and std::declvalto determine the type (which will still give the right answer if I change the implementation of redi::zip)

为什么要把这个类型放到一个结构中呢?它并不是设计成这样使用的(我应该知道,我写了它!)但是如果需要,您可以使用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. why are you creating a typedef for the struct? This is C++ not C, stop it.

注意:为什么要为结构体创建类型定义?这是c++,不是C,停下来。

I have no idea what the type of auto i is, making it harder to reuse expertise and learn from examples.

我不知道我是什么类型的汽车,使它更难重用专业知识和从例子中学习。

Get used to it. Do you know the type that std::bind returns? Do you know the type that std::mem_fn returns? Do you know the type that a lambda expression creates? No, you don't need to know, all you need to know is what properties it has and what you can do with it, not what it's called or what types it contains.

要去适应它。你知道std::bind return是什么类型吗?您知道std::mem_fn返回的类型吗?你知道lambda表达式创建的类型吗?不,你不需要知道,你只需要知道它有什么属性,你可以用它做什么,而不需要知道它叫什么或包含什么类型。

#2


8  

Try to change auto into a char and read the error message.

尝试将自动转换为字符并读取错误消息。

#3


8  

Would you have found

你会发现

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>() << ' ';

easier to understand?

更容易理解?

#4


3  

The best way to figure out what redi::zip() returns is to look at what redi::zip() returns. =) My IDE lets me jump straight to it by holding Ctrl and clicking zip(). Doesn't yours offer similar features? I can even just hover over zip() in the for() loop, and get a tooltip that gives the function signature - including the return type.

找出redi::zip()返回的最佳方法是查看redi::zip()返回。我的IDE让我通过按住Ctrl并点击zip()直接跳转到它。你们的产品也有类似的特点吗?我甚至可以在for()循环中略过zip(),并得到一个提供函数签名的工具提示——包括返回类型。

You'll need to look at it anyway for typing whatever you'd manually replace 'auto' with, and auto serves the great benefit that it lets you declare types that it's impossible to otherwise declare (like lambda returns, unless doing complex things like decltype, which has the same flaw you don't like about auto).

你需要看无论如何手动输入任何你想取代“汽车”,和汽车服务大有好处,它允许您声明类型,否则无法申报(如λ的回报,除非像decltype做复杂的事情,你有相同的缺陷不喜欢汽车)。

When IDEs support C++11 more, your intellisense would kick in better, and it'll be clearer what the type is. I'm sure in a year or less, most up-to-date IDEs will tell you the auto's true type when hovered over.

当ide支持更多的c++ 11时,您的智能感知会更好地发挥作用,并且它将更清晰地显示类型。我敢肯定,在一年或更短的时间内,大多数最新的ide都能告诉您当鼠标悬停时汽车的真正类型。

The gains of auto far outweigh the losses, though, yes, there is a tiny loss that will become even tinier with good IDE support. Almost everything has pros and cons.

汽车的收益远远超过损失,但是,是的,有一个小的损失将变得更小,有良好的IDE支持。几乎每件事都有利弊。

#5


2  

I disagree with your assertion that not knowing the type of i is "making it harder to reuse expertise and learn from examples". The type of i is "that thing that zip returns". Why isn't that sufficient?

我不同意您的断言,即不知道我的类型“使重用专业知识和从示例中学习变得更加困难”。i的类型是“zip返回的那个东西”。为什么这不是足够了吗?

#6


1  

Apart from other answers, I like to use <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();
}

Which outputs:

输出:

std::pair<int, int>

You can also use typeid() from <typeinfo>:

您还可以使用 中的typeid():

auto p = std::make_pair(1, 2);
cout << typeid(p).name() << '\n';

The output is not as understandable as the first example, but still:

输出不像第一个例子那么容易理解,但仍然:

St4pairIiiE