programing tip

'자동'유형 추론 사용-컴파일러가 추론 한 유형을 찾는 방법은 무엇입니까?

itbloger 2020. 11. 4. 07:46
반응형

'자동'유형 추론 사용-컴파일러가 추론 한 유형을 찾는 방법은 무엇입니까?


auto키워드를 사용할 때 컴파일러가 추론 한 유형을 어떻게 알 수 있습니까?

예 1 : 더 간단

auto tickTime = 0.001;

이것은 float또는 a 로 추론 되었습니까?double?

예 2 : 더 복잡함 (그리고 현재 두통) :

typedef std::ratio<1, 1> sec;
std::chrono::duration<double, sec > timePerTick2{0.001};
 auto nextTickTime = std::chrono::high_resolution_clock::now() + timePerTick2;

어떤 유형 nextTickTime입니까?

내가 보내려고 할 때 제가하는 데 문제는있다 nextTickTimestd::cout. 다음과 같은 오류가 발생합니다.

./main.cpp: In function ‘int main(int, char**)’:
./main.cpp:143:16: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
  std::cout << std::setprecision(12) << nextTickTime << std::endl; // time in seconds
            ^
In file included from /usr/include/c++/4.8.2/iostream:39:0,
             from ./main.cpp:10:
/usr/include/c++/4.8.2/ostream:602:5: error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<double, std::ratio<1l, 1000000000l> > >]’
 operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)

구현되지 않은 템플릿을 사용하는 Effective Modern C ++의 아이디어를 사용하고 싶습니다 . 유형이 컴파일러 오류와 함께 출력됩니다.

 template<typename T> struct TD;

이제 자동 변수 var에 대해 정의 후에 다음을 추가하십시오.

 TD<decltype(var)> td;

컴파일러에 대한 오류 메시지를 확인하면 var.


사전 헬퍼 정의가 필요하지 않은 lo-fi 트릭은 다음과 같습니다.

typename decltype(nextTickTime)::_

컴파일러는 _어떤 유형의 멤버가 아니라고 불평합니다 nextTickTime.


다음 은 런타임에 유형 이름을 가져 오는 typeid데 사용 하는 버전입니다 boost::core::demangle.

#include <string>
#include <iostream>
#include <typeinfo>
#include <vector>
using namespace std::literals;

#include <boost/core/demangle.hpp>

template<typename T>
std::string type_str(){ return boost::core::demangle(typeid(T).name()); }

auto main() -> int{
    auto make_vector = [](auto head, auto ... tail) -> std::vector<decltype(head)>{
        return {head, tail...};
    };

    auto i = 1;
    auto f = 1.f;
    auto d = 1.0;
    auto s = "1.0"s;
    auto v = make_vector(1, 2, 3, 4, 5);

    std::cout
    << "typeof(i) = " << type_str<decltype(i)>() << '\n'
    << "typeof(f) = " << type_str<decltype(f)>() << '\n'
    << "typeof(d) = " << type_str<decltype(d)>() << '\n'
    << "typeof(s) = " << type_str<decltype(s)>() << '\n'
    << "typeof(v) = " << type_str<decltype(v)>() << '\n'
    << std::endl;
}

내 시스템에서 이것을 인쇄합니다.

typeof(i) = int
typeof(f) = float
typeof(d) = double
typeof(s) = std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
typeof(v) = std::vector<int, std::allocator<int> >

typeid는 대부분의 경우 변수 유형을 가져 오는 데 사용할 수 있습니다. 컴파일러에 따라 다르며 이상한 결과를 제공하는 것을 보았습니다. g ++에는 기본적으로 RTTI가 있으며 Windows 측에서는 확실하지 않습니다.

#include <iostream>
#include <typeinfo>
#include <stdint.h>
#include <chrono>
#include <ctime>

typedef std::ratio<1, 1> sec;
int main()
{
    auto tickTime = .001;
    std::chrono::duration<double, sec > timePerTick2{0.001};
    auto nextTickTime = std::chrono::high_resolution_clock::now() + timePerTick2;
    std::cout << typeid(tickTime).name() << std::endl;
    std::cout << typeid(nextTickTime).name() << std::endl;

    return 0;
}

./a.out | c++filt

double
std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000000000l> > >

마찬가지로 다니엘 주르가 말했다, 오류 메시지를 읽을 수 :

... _Tp = std::chrono::time_point<
           std::chrono::_V2::system_clock,
           std::chrono::duration<
             double, std::ratio<1l, 1000000000l> > > ...

낮은 기술 솔루션은 마우스 호버입니다 nextTickTime몇 가지의 GUI에서 유형 다른 세트 A를 제공하는 .nextTickTime에서 cout합리적인 찾고 값이나 기능을 선택합니다.

In general if You know what type You get use auto if you don't know it don't use it. Which is a bit counter intuitive.

So if you know its a interator just use auto to reduce the incantations, if the result is some unknown type you have to find out what it is before using auto.

See also Herb, Andrei and Scott discussing auto


This SO answer gives a nice function for printing out the name of a type (actually a couple of implementations).

Additionally this free, open-source, header-only library gives a nice way to print out the value and type of chrono::durations.

Putting these two utilities together:

#include "chrono_io.h"
#include "type_name.h"
#include <iomanip>
#include <iostream>

int
main()
{
    using namespace date;
    typedef std::ratio<1, 1> sec;
    std::chrono::duration<double, sec > timePerTick2{0.001};
    auto nextTickTime = std::chrono::high_resolution_clock::now() + timePerTick2;
    std::cout << type_name<decltype(nextTickTime)>() << '\n';
    std::cout << std::setprecision(12) << nextTickTime.time_since_epoch() << '\n';
}

This output for me:

std::__1::chrono::time_point<std::__1::chrono::steady_clock, std::__1::chrono::duration<double, std::__1::ratio<1, 1000000000> > >
4.8530542088e+14ns

The type deduced by the compiler is in the error message:

/usr/include/c++/4.8.2/ostream:602:5: error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>;
 _Tp = std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<double, std::ratio<1l, 1000000000l> > >]’
  ^^   <-------- the long type name --------------------------------------------------------------------------------------->

It's a complicated type name but it is there in the error message.


As a side note, to effectively print out the value in nextTickTime you should explicitly convert to a suitable std::chrono::duration and output the result of duration::count.

using std::chrono::duration_cast;
using std::chrono::seconds;

auto baseTime = ...;
std::cout << std::setprecision(12) << duration_cast<seconds>(nextTickTime - baseTime).count()
    << std::endl; // time in seconds

Here is a way to force a compile error, which shows the type of tickTime:

struct {} baD = tickTime;

참고URL : https://stackoverflow.com/questions/38820579/using-auto-type-deduction-how-to-find-out-what-type-the-compiler-deduced

반응형