문제

실제로 인텔 컴파일러로 일부 라이브러리를 컴파일하는 데 문제가 있습니다.

이 동일한 라이브러리는 G ++로 올바르게 컴파일되었습니다.

문제는 템플릿으로 인해 발생합니다. 내가 이해하고 싶은 것은 선언입니다**typename** 템플릿 함수 매개 변수 및 기능 본체 내부의 변수 선언

예시:

void func(typename sometype){..
...
typename some_other_type;
..
}

컴파일이 종류의 코드는 다음 오류 (Intel)를 생성합니다 (GCC는 주장하지 않습니다) : 오류가 다음과 같습니다.

../../../libs/log/src/attribute_set.cpp(415): error: no operator "!=" matches these operands
            operand types are: boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> != boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'>
      while (begin != end)
                   ^
          detected during instantiation of "void boost::log_st::basic_attribute_set<CharT>::erase(boost::log_st::basic_attribute_set<CharT>::iter<'\000'>, boost::log_st::basic_attribute_set<CharT>::iter<'\000'>) [with CharT=wchar_t]" at line 438

../../../boost/log/attributes/attribute_set.hpp(115): error: no operator "!=" matches these operands
            operand types are: boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'> != boost::log_st::basic_attribute_set<wchar_t>::iter<'\000'>
              if (it != m_pContainer->end())

내가 이해하고 싶은 것은 함수 본문, 매개 변수 선언 내부의 타이프 이름을 사용하는 것입니다.

전.:

template< typename CharT >
struct basic_attribute_values_view< CharT >::implementation
{

public:
..
..
void adopt_nodes( **typename attribu**te_set_type::const_iterator& it, **typename attribut**e_set_type::const_iterator end)
    {
        for (; it != end; ++it)
            push_back(it->first, it->second.get());
    }

다른 파일에서 나는 :

template< typename CharT >
class basic_attribute_set
{
    friend class basic_attribute_values_view< CharT >;

    //! Self type
    typedef basic_attribute_set< CharT > this_type;

public:
    //! Character type
    typedef CharT char_type;
    //! String type
    typedef std::basic_string< char_type > string_type;
    //! Key type
    typedef basic_slim_string< char_type > key_type;
    //! Mapped attribute type
    typedef shared_ptr< attribute > mapped_type;

    //! Value type
    typedef std::pair< const key_type, mapped_type > value_type;
    //! Allocator type
    typedef std::allocator< value_type > allocator_type;
    //! Reference type
    **typedef typename allocator_type::reference reference;**
도움이 되었습니까?

해결책

사용해야합니다 typename 소위 "종속 유형"의 경우. 그것들은 템플릿 인수에 의존하고 템플릿이 인스턴스화 될 때까지 알려지지 않은 유형입니다. 아마도 예를 사용하여 가장 잘 설명 될 것입니다.

struct some_foo {
  typedef int bar;
};

template< typename Foo >
struct baz {
  typedef Foo::bar barbar; // wrong, shouldn't compile

  barbar f(); // would be fine if barbar were a type

  // more stuff...
};

저것 typedef 정의 barbar 필요한 것입니다 typename 컴파일러가 홍보 구문 오류를 템플릿을 확인할 수 있도록 ~ 전에 콘크리트 유형으로 인스턴스화됩니다. 그 이유는 컴파일러가 처음으로 템플릿을 볼 때 (아직 콘크리트 템플릿 매개 변수로 인스턴스화되지 않았을 때) 컴파일러는 Foo::bar 유형입니다. 아시다시피, 나는 의도 할 수 있습니다 baz 이와 같은 유형과 인스턴스화됩니다

struct some_other_foo {
  static int bar;
};

어떤 경우 Foo::bar would refer to an 물체, 유형이 아니라 정의 baz::bar 구문 넌센스 일 것입니다. 알지 못하고 Foo::bar 유형을 말하면 컴파일러는 내에서 아무것도 확인할 기회가 없습니다. baz 직간접 적으로 사용하고 있습니다 barbar 가장 어리석은 오타조차도 baz 인스턴스화됩니다. 적절한 사용 typename, baz 이렇게 보인다 :

template< typename Foo >
struct baz {
  typedef typename Foo::bar barbar;

  barbar f();

  // more stuff...
};

이제 컴파일러는 적어도 그것을 알고 있습니다 Foo::bar 유형의 이름이어야합니다. barbar 유형 이름도. 그래서 선언 f() 구문도 좋습니다.

그건 그렇고, 유형 대신 템플릿과 비슷한 문제가 있습니다.

template< typename Foo >
struct baz {
  Foo::bar<Foo> create_wrgl(); // wrong, shouldn't compile
};

컴파일러가 "볼 때" Foo::bar 그것이 무엇인지 모릅니다 bar<Foo 컴파일러가 후행에 대해 혼란 스러울 수있는 비교 일 수 있습니다. >. 여기서도 컴파일러에게 힌트를 주어야합니다. Foo::bar 템플릿의 이름이어야합니다.

template< typename Foo >
struct baz {
  Foo::template bar<Foo> create_wrgl();
};

조심하십시오 : 특히 Visual C ++는 여전히 적절한 2 상 조회를 구현하지 않습니다 (본질적으로 : 템플릿이 인스턴스화 될 때까지 실제로 템플릿을 점검하지는 않습니다). 따라서 종종 a를 놓치는 잘못된 코드를 받아들입니다 typename 또는 a template.

다른 팁

의 요점 typename 키워드는 컴파일러에게 분명하지 않은 상황에서 무언가가 타이프 이름임을 알리는 것입니다. 이 예를 들어보세요 :

template<typename T>
void f()
{
    T::foo * x;
}

~이다 T::foo 유형, 즉 우리가 포인터를 선언하거나 T::foo 정적 변수이며 곱셈을하고 있습니까?

컴파일러는 템플릿을 읽을 때 어떤 t가 될 수 있는지 전혀 모르기 때문에 두 경우 중 어느 것이 올바른지 전혀 모른다.

표준은 컴파일러가 후자의 경우를 가정하고 해석해야한다고 지시합니다. T::foo The TypeName으로 선행되는 경우 typename 다음과 같은 키워드 :

template<typename T>
void f()
{
    typename T::foo* x; //Definitely a pointer.
}

코드에 :

void func(typename sometype)
{
    .....typename some_other_type;
    ..
}

위의 코드가 템플릿의 일부가 아닌 경우 이전 버전의 G ++가 아니라면 g ++를 사용하여 컴파일 할 수 없습니다.

경험이 풍부한 FC9 또는 GNU C/++ 버전 4.2x는이를 오류로보고 할 것입니다.

typename only can be used in template code

FC8 또는 GNU C/++ 4.1X는 그렇지 않을 수 있습니다.

참조하십시오

http://code.google.com/p/effocore/source/browse/trunk/devel/effo/codebase/addons/inl/include/ringed_inl.h
and 
http://code.google.com/p/effocore/source/browse/trunk/devel/effo/codebase/addons/inl/include/cont_inl.h

더 많은 템플릿 및 타이프 이름 예제.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top