4

I have a simple question related to function template. Assuming I have a header containing a class with a template method called f :

class test
{
public:
   template < class T > void f(T t) {}
};

If this header is included in several .cpp files, and each of these .cpp calls f with the same type (let's say int), can I take the pointer of the function somewhere else in the code? Considering there are potentially several definitions, will the linker keep only one?

IAmInPLS
  • 4,051
  • 4
  • 24
  • 57
Al227
  • 151
  • 7
  • 1
    Similar question, although it does not explicitly mention member function templates: https://stackoverflow.com/questions/7670000/addresses-of-identical-function-template-instantiations-across-compilation-units – melak47 Apr 05 '16 at 08:58

2 Answers2

0

If this header is included in several .cpp files, and each of these .cpp calls f with the same type (let's say int), can I take the pointer of the function somewhere else in the code?

Yes you can take the address of a specific instantiation of a template function.

Considering there are potentially several definitions, will the linker keep only one?

That is an implementation detail.
I would bet that most implementation will try and remove duplicates, but I don't think there is requirement as long as the behavior is consistent.

Martin York
  • 257,169
  • 86
  • 333
  • 562
-1

The C++ Standard says in section 14/1,

A template defines a family of classes or functions.

It does not mention function pointers. So what you are attempting to do is not possible.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 4
    I don't think he literally meant "take the address of the function template", but rather the address of a particular instantiation. – melak47 Apr 05 '16 at 09:03
  • ...which you can't do due to the omission of that possibility in the standard. Quite possibly you could get it to work for a static template function, but I question its portability. – Bathsheba Apr 05 '16 at 09:05
  • yes my concern is about a pointer on that specific type instntiation (so in my example, taking the pointer of the function f). Can i do that ? Is it portable? thanks – Al227 Apr 05 '16 at 09:08
  • "Can i do that?" Possibly. "Is it portable?". No. – Bathsheba Apr 05 '16 at 09:12
  • @Bathsheba Why wouldn't it be portable? I don't see what the issue is, seeing as there needs to be a single definition of that function. – TartanLlama Apr 05 '16 at 09:13
  • @TartanLiama, your remark is what i initially thought (only one definiton), however in case of member function template, i think this doesn't apply anymore, hence this topic – Al227 Apr 05 '16 at 09:13
  • I don't think it falls into the 14/1 standard definition. One thought is that a compiler reserves the right to inline all the definitions. – Bathsheba Apr 05 '16 at 09:14
  • I don't really see what that clause has to do with this. The function template defines a family of functions, but an instantiation of that template is a single function which you can take the address of. – TartanLlama Apr 05 '16 at 09:19
  • I don't agree with that. What's stopping the compiler from inlining that function? – Bathsheba Apr 05 '16 at 09:20
  • it can inlining it, in which case the adress doesn't exist, OR IT COULD ALSO have a definition per cpp file (if each of these cpp file instantiate it, each cpp file doesn't know what happen in others at compile time), so you see, my question is complex – Al227 Apr 05 '16 at 09:22
  • Yes indeed your question is a good one. Perhaps I'm a dogmatic old cat, but I still stick to my assertion that this is not possible. – Bathsheba Apr 05 '16 at 09:23
  • The fact that you take the address of it. If you extract a pointer to the function, the compiler has to emit a non-inlined version for that to point at (unless it can do other optimizations to eliminate the need for that pointer). Maybe I'm wrong, but I don't see how this is different for pointers to instantiated member functions and other functions. – TartanLlama Apr 05 '16 at 09:23
  • your reasoning is probably what happens, i.e the fact that you ask a pointer forces the linker to keep at least one definition, but i am sure that i will get the same pointer evrytime if a ask for a pointer agaiun, if several implementations of f exists? – Al227 Apr 05 '16 at 09:25
  • and sadly ODR cannot be invoked for member template function : cf standard as pointed by melak47 : There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member of a class template (14.5.1.3), member function of a class template <=== HERE – Al227 Apr 05 '16 at 09:28
  • 1
    I think this is guaranteed by `[dcl.fct.spec]/4`: "An inline function with external linkage shall have the same address in all translation units" – TartanLlama Apr 05 '16 at 09:28
  • I'll wiki this. My contribution thus far has been minimal and the comments are interesting. – Bathsheba Apr 05 '16 at 09:30
  • yeah, I tartanLiama remarked, this actually is a member template function, not a member function of a class template... but my initial problem was a class template with a member function, too, i just gave a bad code example, but the question is essentially the same – Al227 Apr 05 '16 at 09:36