I wrote a class template that take a single template parameter, something like
1 2 3 4 5 6 7 8 9 10
template <typename T>
class Foo {
protected:
T _bar;
public:
void call_method_on_bar(){_bar.do_something();};
//more stuff
private:
//more stuff
}
how can I be sure that T provides an interface for the method do_something?
Alternatively, how can I be sure the compiler complains if I declare Foo<double> (I am pretty sure I cannot compile 1e3.do_something();)
(I am using the intel compiler, maybe there is a useful flag I can set?)
How can I be sure that T provides an interface for the method do_something?
If T does not provide a compatible (i.e., well-formed, type-correct, accessible) method do_something(), the code will fail to compile. This is guaranteed by the language, templates are instantiated at compile time and are therefore statically type-checked. To this end, generic C++ code is duck-typed. Anything that satisfies the requirements can be used, but any thing that doesn't won't compile.
If you wanted to make a decision based on whether or not T provides do_something(), you can do that too - even controlling the generation of code based on the required properties of any T. You would ordinarily use a language feature referred to as SFINAE (for "substitution failure is not an error") for that purpose.
template <typename T>
class Foo {
T _bar;
public:
void call_method_on_bar()
{
_bar.do_something();
}
};
int main()
{
Foo<double> fubar;
fubar.call_method_on_bar();
}
In instantiation of 'void Foo<T>::call_method_on_bar() [with T = double]':
14:28: required from here
7:5: error: request for member 'do_something' in
'((Foo<double>*)this)->Foo<double>::_bar', which
is of non-class type 'double'
The compiler has to report an error if the requirements for T are not fulfilled.