Questions tagged [dependent-name]

A C++ dependent name is a name that depends on a template argument. A non-dependent name does not depend on template arguments. The compiler resolves these two types of names at different points in time.

The issue of dependent and non-dependent names arises in templates. Two instantiations of the same class template may have different members, different types. Names that depend on a template argument are dependent names. Names that don't are non-dependent names. The compiler resolves non-dependent names at the point where a template is defined. Resolution of dependent names is deferred until the point where a template is instantiated.

This can lead to some strange compilation errors:

template <class T> class A
{
protected:
   A(T v) : x(v) {}
   T f() { return x; }
private:
   T x;
};

template <class T> class B : public A<T>
{
public:
   B() : A<T>(42) {}
   T g () { return f(); } // Compilation error
};

The above fails to compile because of the non-dependent usage of f in B::g(). The solution is to turn that non-dependent name into a dependent name. Using a using declaration (using A<T>::f;), using a qualified name (return A<T>::f();) or explicitly using this (return this->f();) are three ways to turn the unqualified, non-dependent f into a dependent name.

59 questions
1206
votes
8 answers

Where and why do I have to put the "template" and "typename" keywords?

In templates, where and why do I have to put typename and template on dependent names? What exactly are dependent names anyway? I have the following code: template // Tail will be a UnionNode too. struct UnionNode :…
MSalters
  • 159,923
  • 8
  • 140
  • 320
39
votes
3 answers

Conditional operator's return type and two-phase lookup

Consider the following snippet: struct Base { }; struct Derived : Base { }; void f(Base &) { std::cout << "f(Base&)\n"; } template void g() { Derived d; f(T{} ? d : d); // 1 } void f(Derived &) { std::cout <<…
Quentin
  • 58,778
  • 7
  • 120
  • 175
28
votes
2 answers

Two phase name lookup for C++ templates - Why?

Why does the C++ standard define two phase lookup for templates? Couldn't non dependent declarations and definitions' lookups be deferred to the instantiation stage as well?
Xyand
  • 4,290
  • 3
  • 33
  • 59
25
votes
2 answers

static_assert dependent on non-type template parameter (different behavior on gcc and clang)

template struct Hitchhiker { static_assert(sizeof(answer) != sizeof(answer), "Invalid answer"); }; template <> struct Hitchhiker<42> {}; While trying to disable general template instantiation with static_assert I discovered that the…
bolov
  • 58,757
  • 13
  • 108
  • 182
23
votes
2 answers

Why does this template function not behave as expected?

I was reading about template functions and got confused by this problem: #include void f(int) { std::cout << "f(int)\n"; } template void g(T val) { std::cout << typeid(val).name() << " "; f(val); } void…
20
votes
2 answers

Name lookup differences between g++ and MSVS

Consider this code: #include namespace N { class A {}; void f(A a) { std::cout << "N::f\n"; } } void f(int i) { std::cout << "::f\n"; } template class Base { public: void f(T x) { std::cout << "Base::f\n";…
oz1cz
  • 4,837
  • 5
  • 29
  • 54
16
votes
2 answers

calling template function of template base class

Possible Duplicate: Where and why do I have to put the “template” and “typename” keywords? Here's the code: template class base { public: virtual ~base(); template void foo() { std::cout <<…
Daniel K.
  • 857
  • 3
  • 9
  • 21
15
votes
1 answer

What is the rule that allows `this->` to access members of dependent base classes?

As we know, the code below is ill-formed because the member x is in a dependent base class. However, changing x to this->x on the indicated line would fix the error. template struct B { int x; }; template struct C :…
Brian Bi
  • 91,815
  • 8
  • 136
  • 249
14
votes
1 answer

Comparison operator for std::vector fails to find comparison operator for T

The following very simple code won't compile #include #include namespace Foobar { struct Test { std::string f; std::uint16_t uuid; }; } bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){ …
14
votes
3 answers

Why is template function of data member a dependent name only when qualifying with "this"?

struct Bar { template void baz() { } }; template struct Foo { Bar bar; Foo() { bar.baz(); } }; int main() { return 0; } This code compiles fine (in GCC 4.7), but if I prefix the call…
Joseph Thomson
  • 7,955
  • 1
  • 24
  • 34
13
votes
1 answer

template base class typedef members invisible

I'm aware of the fact that the 'dependent names' are not visible to the compiler by default. But I was told in answers to other SO questions (here, here, and ultimately on the C++ faq) that a using declaration may help. So I tried. A template base…
xtofl
  • 38,207
  • 10
  • 95
  • 177
12
votes
2 answers

Accessing types from dependent base classes

Does anyone know why using-declarations don't seem to work for importing type names from dependent base classes? They work for member variables and functions, but at least in GCC 4.3, they seem to be ignored for types. template struct…
Trevor Robinson
  • 13,611
  • 5
  • 64
  • 66
11
votes
3 answers

Why `this` is a type-dependent expression even if the template class has no base class?

The following code can be compiled without error: template struct A { void f() { this->whatever; } // whatever is not declared before }; int main() { A a; } And I know it's because this is a type-dependent expression,…
Carousel
  • 698
  • 4
  • 13
10
votes
5 answers

multiple nested dependent names - where to stick the typename keyword?

This question was inspired by this other question. While trying to answer that question, I understood that I have a lot of questions myself. So... Consider the following: struct S1 { enum { value = 42 }; }; template struct S2 { …
Armen Tsirunyan
  • 120,726
  • 52
  • 304
  • 418
10
votes
3 answers

Why is it not required to use typename for dependent types in the following case?

I have been reading about removing reference of a type, here. It gives the following example: #include // std::cout #include // std::is_same template void print_is_same() { std::cout <<…
LernerCpp
  • 169
  • 1
  • 10
1
2 3 4