4

Possible Duplicate:
C++ difference of keywords 'typename' and 'class' in templates

I already know in many cases that class cannot be replaced by typename. I am only talking about the opposite: replacing typename by class.

Someone pointed out that only typename can be used here:

template<class param_t> class Foo 
{     
        typedef typename param_t::baz sub_t; 
};

But I do not see any problem replacing typename with class here (in MSVC). To recap, can I ALWAYS replace typename with class? Please give an example if not.

Community
  • 1
  • 1
Rio Wing
  • 662
  • 5
  • 12
  • 1
    In the above case you and some compilers might differ :) – parapura rajkumar Nov 14 '11 at 01:53
  • 2
    Already answered here: [C++ difference of keywords 'typename' and 'class' in templates](http://stackoverflow.com/questions/2023977/c-difference-of-keywords-typename-and-class-in-templates) – bobbymcr Nov 14 '11 at 01:55
  • Could you please clarify what your actual question is? – Kerrek SB Nov 14 '11 at 02:04
  • "Please give an example if not." You already have an example — for dependent types, you *have* to use `typename`, that's what this keyword was introduced for. – Cat Plus Plus Nov 14 '11 at 02:25
  • But I use 'class' instead, it works fine. – Rio Wing Nov 14 '11 at 02:34
  • 2
    @Rio: It's not fine. You probably use MSVC, which doesn't require `typename` in places where standard does. That you can use `class` is probably an artefact from inheriting `struct x var;` syntax from C. It's a red herring. – Cat Plus Plus Nov 14 '11 at 02:36
  • Why this question is being closed as duplicate ? That thread doesn't answer OP's question. I recall there is a corner case where you can only use `typename` and not `class`. – iammilind Nov 14 '11 at 02:48
  • Thanks Cat Plus Plus, I am using Microsoft C++, which is the only one I have. I feel you are right. – Rio Wing Nov 14 '11 at 03:20

2 Answers2

4

No, you cannot always replace one with the other.

The two keywords typename and template are necessary for name disambiguation to inform the compiler whether a dependent name is a value (no keyword needed), a type (needs typename), or a template (needs template):

template <typename T> struct Foo
{
  char bar()
  {
    int x = T::zing;                 // value, no decoration for disambiguation of "T::zing"

    typedef typename T::bongo Type;  // typename, require disambiguation of "T::bongo"

    return T::template zip<Type>(x); // template, require disambiguation of "T::zip"
  }
};

Only the keywords typename and template work in those roles; you cannot replace either by anything else.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • +1, [it's not allowed as soon as you use bar()](http://www.ideone.com/xiJHs) strangely it seems that if `class` instead of `typename` will work, if used inside `Foo` directly (not inside function). – iammilind Nov 14 '11 at 02:56
  • @iammilind: With `class` in place of `typename`, my GCC says, `error: ‘class ****’ resolves to ‘**** {aka int}’, which is is not a class type`. So you cannot use `class` as a generic disambiguator. However, it seems that you can use it to request a type of class-type explicitly. I didn't know that. – Kerrek SB Nov 14 '11 at 02:56
0

You cannot use typename for template template arguments:

template <
    template <typename> class Container>, // cannot use typename for class
    typename T
  > struct TestMe
{
    Container<T> _data;
    // ... etc.
};

This is because only classes can be templated.

sehe
  • 374,641
  • 47
  • 450
  • 633