3
template <typename T>
void func(){
  T* t = new T();
  t->do_something();
  ...
}

In this case, how does the compiler know that typename T will have a method do_something() defined on it? In Java we can specify what interface a generic class extends, but C++ apparently doesn't have the same syntax. So what happens if we call func<AClassThatDoesntHaveDoSomethingDefined>()?

OneZero
  • 11,556
  • 15
  • 55
  • 92
  • Possible duplicates: http://stackoverflow.com/q/122316/365102, http://stackoverflow.com/a/15671344/365102 – Mateen Ulhaq Apr 04 '16 at 19:11
  • @MateenUlhaq No. I'm not asking how to add constraints on templates. I'm more curious why C++ allows such code to compile and how it handles the case when the called function is not defined. – OneZero Apr 04 '16 at 19:12
  • 1
    @OneZero The rules of the language are that until the template is instantiated, very few checks are made. Once the template is instantiated, though - there's enough information to know there's a problem, no? – Ami Tavory Apr 04 '16 at 19:13
  • Um, **extending** a class (in Java) is more like **deriving from** a class in C++. It has nothing to do with templates. – Pete Becker Apr 04 '16 at 19:44

2 Answers2

7

The compiler doesn't know until you instantiate the template function... with T. Then it will lookup whether T has such methods... If not, You get an error.

Think of template types like placeholders, there is no code generated for a template function, until it is instantiated with a type. So if you have such function and its never called, though it will still undergo some syntax conformance checks by the compiler, it wouldn't be part of the assembly. Thats one of the many features of templates.

When you call func<AClassThatDoesntHaveDoSomethingDefined>(), the compiler substitutes the typename T with AClassThatDoesntHaveDoSomethingDefined. And it will attempt to create a function like this:

void func(){
  AClassThatDoesntHaveDoSomethingDefined* t = new AClassThatDoesntHaveDoSomethingDefined();
  t->do_something();
  ...
}

The usual rules for compilation follows... if do_something() isn't defined, you will get an error.

There's a little more information on templates here: https://isocpp.org/wiki/faq/templates

WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
1

Templates don't know nuthin' until they are used. As soon as they are used, the template is turned into code with the template arguments substituted in for the place holders. This generated code is then compiled, and if any of those substituted arguments does not live up to the requirements of this newly generated code, then you get an error message.

Think of it in stages.

You define the following template

template<T>
bool func(T val)
{
    return val.getstate();
}

During compilation,

std::string test;
if (func(test))

is found and triggers the template. The compiler then runs off and creates

bool func(std::string val)
{
    return val.getstate();
}

from the template. Some time later during compilation, this generated function will be compiled and find std::string::getstate does not exist, producing an error message.

user4581301
  • 33,082
  • 7
  • 33
  • 54