Calling a method on an unknown type through a template function

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Calling a method on an unknown type through a template function



The C++ language allows me to write a template function that will call a method on the object that gets passed to the function.



The concern here is when I do this, my IDE (NetBeans 8.2) will complain that it can't resolve the method. This makes sense because the type that will be used for "T" is not known until I try to compile the code, but the fact that it gives me a warning makes me a little concerned about whether or not doing this is bad programming practice.



Consider the following code:


struct S1
void method() const
cout << "Method called from S1!" << endl;

;

struct S2
void method() const
cout << "Method called from S2!" << endl;

;

template <typename T>
void call_method(const T& object)

// IDE reports a warning "can't resolve the template based identifier method."
object.method();



Usage example:


S1 obj1;
S2 obj2;

call_method(obj1);
call_method(obj2);



This code will compile and work just fine, but the IDE will always complain. Is this okay to do? Or is there a better design that I should know about to get the same desired results.



The desired result is to write a function that can use S1 or S2 objects without caring which one it is as long as they provide an interface that includes "method()".



Assume I do not have access to the source code of S1 and S2 so I can't make changes to them. (For example I cannot make them inherit from a common base class and use dynamic polymorphism instead of a template function to achieve the same effect).





That's very fine and even common. It's part of the generics that templates brings, making things more generic.
– Some programmer dude
Aug 6 at 16:58




1 Answer
1



This is perfectly OK and is commonly used in a lot of cases. Dealing with a generic container from the standard library or different types of iterators for example.



If the type passed in does not have an appropriate method you will get a compilation error.



If you want you can use SFINAE to make sure the type passed in is among the types you expect. Can be good or useful sometimes, but often not needed.



Update: static_assert is another useful way of putting constraints on a template as pointed out by @Evgeny


static_assert





Thanks @super, do you know of any good sources for explaining SFINAE? I'm having a little bit of trouble wrapping my head around it.
– tjwrona1992
Aug 6 at 17:16





If overload resolution is not the issue, static_assert is probably a better choice than SFINAE.
– Evg
Aug 6 at 17:19


static_assert





@tjwrona1992 This seems to be a fairly straight forward explanation.
– super
Aug 6 at 18:28





@tjwrona1992 SFINAE is about eliminating a template that would otherwise be an ambiguous overload for a particular instantiation. In your case, you might have an S3 that provides method as a free function, so you write call_method(const S3 & obj);. However you now have to stop call_method<S3> from being considered
– Caleth
Aug 6 at 18:29


S3


method


call_method(const S3 & obj);


call_method<S3>






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard