2

I have a code in VC2010 which I've reduced to a small example.

Test.h:

#pragma once

template <typename TPixel>
struct Image
  {
  typedef TPixel PixelType;
  };

template <typename TImageType>
struct Operation
  {
  void DoOperation()
    {
    ImageType::PixelType value = 0;   
// I've done a misprint here. It should be TImageType::PixelType
    }
  };

Test.cpp:

void Test()
  {
  typedef Image<char> ImageType;

  Operation<ImageType> op;
  op.DoOperation();
  }

As I expected, that produces an error.

test.h(14): error C2653: 'ImageType' : is not a class or namespace name

Now, let's change test.cpp just a little bit.

typedef Image<char> ImageType;

void Test()
  {
  Operation<ImageType> op;
  op.DoOperation();
  }

Now it compiles! Surprisingly enough, ImageType in DoOperation() now matches with the global typedef in test.cpp.

My question: why does it compile? Is that a Visual C++ bug or a standard behavior?

Andriy
  • 8,486
  • 3
  • 27
  • 51

1 Answers1

3

I take it that test.cpp includes test.h before the typedef, so it's actually

#include "test.h"
typedef Image<char> ImageType;

void Test()
  {
  Operation<ImageType> op;
  op.DoOperation();
  }

Completed like this, it is indeed a bug, or standard nonconforming behavior with regard to two phase lookup. Names that do not depend on a template parameter should be resolved relative to the point of declaration of the template.

I guess this is known behavior.

Community
  • 1
  • 1
jpalecek
  • 47,058
  • 7
  • 102
  • 144