templates problem ('typename' as not template function parameter)

前端 未结 3 784
走了就别回头了
走了就别回头了 2020-12-16 06:44

Actually I\'ve a problem with compiling some library with intel compiler.

This same library has been compiled properly with g++.

Problem is caused by templat

相关标签:
3条回答
  • 2020-12-16 07:20

    You need to use typename for so-called "dependent types". Those are types that depend on a template argument and are not known until the template is instantiated. It's probably best explained using an example:

    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...
    };
    

    That typedef defining barbar is one that requires a typename in order for the compiler to be able to check the template for blatant syntactic errors before it is instantiated with a concrete type. The reason is that, when the compiler sees the template for the first time (when it's not instantiated with concrete template parameters yet), the compiler doesn't know whether Foo::bar is a type. For all it know, I might intent baz to be instantiated with types like this one

    struct some_other_foo {
      static int bar;
    };
    

    in which case Foo::bar would refer to an object, not a type, and the definition of baz::bar would be syntactic nonsense. Without knowing whether Foo::bar refers to a type, the compiler has no chance to check anything within baz that's directly or indirectly using barbar for even the most stupid typos until baz is instantiated. Using the proper typename, baz looks like this:

    template< typename Foo >
    struct baz {
      typedef typename Foo::bar barbar;
    
      barbar f();
    
      // more stuff...
    };
    

    Now the compiler at least knows that Foo::bar is supposed to be the name of a type, which makes barbar a type name, too. So the declaration of f() is syntactical OK, too.

    By the way, there's a similar problem with templates instead of types:

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

    When the compiler "sees" Foo::bar it doesn't know what it is, so bar<Foo could just as well be a comparison, leaving the compiler confused about the trailing >. Here, too, you need to give the compiler a hint that Foo::bar is supposed to be the name of a template:

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

    Beware: Notably Visual C++ still doesn't implement proper two-phase lookup (in essence: it doesn't really check templates until they are instantiated). Therefor it often accepts erroneous code that misses a typename or a template.

    0 讨论(0)
  • 2020-12-16 07:21

    The point of the typename keyword is to tell the compiler that something is a typename, in situations where it's not obvious. Take this example:

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

    Is T::foo a type, meaning we are declaring a pointer, or is T::foo a static variable, and we are doing a multiplication?

    Since the compiler has no idea of what T could be at the time it reads the template, it has no idea which of the two cases is correct.

    The standard dictates that the compiler should assume the latter case, and only interpret T::foo as a typename if it is preceded by the typename keyword, like this:

    template<typename T>
    void f()
    {
        typename T::foo* x; //Definitely a pointer.
    }
    
    0 讨论(0)
  • Upon your code:

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

    If the above code is not a part of a template, then it cannot be compiled using g++, unless the old version of g++.

    As my experienced, FC9 or GNU C/++ version 4.2x will report it as an error, it'll complain:

    typename only can be used in template code
    

    while FC8 or GNU C/++ 4.1x may not.

    Please see

    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
    

    for more template and typename examples.

    0 讨论(0)
提交回复
热议问题