4

In the following long list of codes, please look for three places:

  1. // "this->" can be omitted before first data[0]

and

  1. // Compile error, if "this->" is omitted before first data[0]

and

  1. // likewise, "this->" is required.

I don't know why sometimes "this->" can be omitted, and sometime can't.

The compile error is: main.cpp:19:3: error: 'data' was not declared in this scope

Is it just a compiler bug? My compiler is GCC v4.8.1 and v4.8.2. Thanks. BTW, QtCreator's default intelli-sense, in fact, can recognize 'data[0]' without "this->" in all three places.

Here's the code list:

template <typename T>
struct Vec3_
{
    T data[3];
    inline Vec3_<T> & operator =(const Vec3_<T> & rhs) {
        if (this != &rhs) {
            data[0] = rhs.data[0];  // "this->" can be omitted before first data[0]
            data[1] = rhs.data[1];
            data[2] = rhs.data[2];
        }
        return *this;
    }
};

template <typename T>
struct Vec3i_: Vec3_<T>
{
    inline Vec3i_<T> & operator ^=(const Vec3i_<T> & rhs) {
        data[0] ^= rhs.data[0];     // Compile error, if "this->" is omitted before first data[0]
        this->data[1] ^= rhs.data[1];
        this->data[2] ^= rhs.data[2];
        return *this;
    }
    inline Vec3i_<T> operator ^(const Vec3i_<T> & rhs) const {
        Vec3i_<T> tmp;
        tmp[0] = this->data[0] ^ rhs.data[0];  // likewise, "this->" is required.
        tmp[1] = this->data[1] ^ rhs.data[1];
        tmp[2] = this->data[2] ^ rhs.data[2];
        return tmp;
    }
};

Vec3i_<int> A;

int main(int, char**) { return 0; }

== update ==

Since someone has pointed out a very similar question (may possibly a duplicate) and answers, and the title of that question is even descriptive, I changed my title similar to that one (except the parameter dependency difference)

Yet after reading the answers to that question, I am still confused. The answers pointed to an FAQ [link here] saying that if a variable is a nondependent name, the compiler will not search for the name in the base template class. However, in this example, the variable (data) is a dependent name, since it is of type T, and T is the template variable.

I am still open for answers.

Robin Hsu
  • 4,164
  • 3
  • 20
  • 37
  • 1
    This question has been asked many times here. You are assuming that all `Vec3i_` will have an inherited data member named `data`. This is not the case. You can easily create a specialization of `Vec3_` that doesn't have such a member. This is why you have to be explicit and use `this`. – David Hammen Dec 15 '14 at 08:46
  • @David Hammen, Could you give me an example how to specialize a `Vec3_` so that it does not have `data` as its member? I am sorry for not finding those "many questions" as you said. Perhaps my search keywords are bad. – Robin Hsu Dec 15 '14 at 08:52
  • @juanchopanza: I have read the answer you pointed out, but am not quite satisfied. The answer pointing to an FAQ, saying that a nondependent name will not be looked up in the base class, but in my example, `data` is a dependent name, right? `data` has its type `T` which depends on template parameter `T`, right? – Robin Hsu Dec 15 '14 at 08:56
  • Just because you've shown the compiler one example where a `Vec3_` does indeed have a data member named `data` does not mean the compiler can trust this will always be the case. The compiler must be able to accommodate stuff such as `template<> struct Vec3_ {};` – David Hammen Dec 15 '14 at 09:09
  • Do you mean: Even if in my case, `data` will always be a member of `Vec3_`, but in some other case (not my example), it won't. The compiler is not smart enough to figure it out. Thus the compiler won't trust `data` to be a member, and thus we need to use `this->` to force resolution of the name after template specialization, right? – Robin Hsu Dec 15 '14 at 09:57
  • 2
    Exactly. The compiler cannot figure it out. The class that will eventually be formed from your template doesn't exist at the time you define that template. The compiler instantiates the template at the point in your code where you use it -- and by then you might have introduced a parent template class specialization that doesn't have a data member named 'data'. – David Hammen Dec 15 '14 at 12:18

0 Answers0