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.