public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Can you use a function reference passed in a template argument?
@ 2023-11-09 20:46 Arthur Schwarz
  2023-11-09 21:02 ` Thomas Bleher
  2023-11-09 21:11 ` Jonathan Wakely
  0 siblings, 2 replies; 8+ messages in thread
From: Arthur Schwarz @ 2023-11-09 20:46 UTC (permalink / raw)
  To: gcc-help


Is there any way to use a function passed as an argument to a template 
(example below)? Couldn't the existence of the referenced function be 
established durint instantiation (Stack<some class> obj)? I realize that 
just doing analysis of the template that the existence of a referenced 
function can't be determined, but during instantiation it can be validated.

As a nit, the repeated instances of "../header/" in the error message is 
an annoyance.

Diagnostic message and code given below.

thanks
art

../header/../header/../header/../header/Stack.h: In member function 
‘std::string Stack<T>::toString()’:
../header/../header/../header/../header/Stack.h:184:46: error: expected 
primary-expression before ‘.’ token
   184 |       str << setw(3) << s.size() << ": " << T.toString();
       |                                              ^

# include <iomanip>
# include <sstream>

using namespace std;
template <class T>
class Stack {
    string toString() {
       stringstream str;
       str << setw(3) << s.size() << ": " << T.toString();
       return str.str();
    };
};


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 20:46 Can you use a function reference passed in a template argument? Arthur Schwarz
@ 2023-11-09 21:02 ` Thomas Bleher
  2023-11-09 21:07   ` Arthur Schwarz
  2023-11-09 21:11 ` Jonathan Wakely
  1 sibling, 1 reply; 8+ messages in thread
From: Thomas Bleher @ 2023-11-09 21:02 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

* Arthur Schwarz <home@slipbits.com> [2023-11-09 21:46]:
> Is there any way to use a function passed as an argument to a template
> (example below)? Couldn't the existence of the referenced function be
> established durint instantiation (Stack<some class> obj)? I realize that
> just doing analysis of the template that the existence of a referenced
> function can't be determined, but during instantiation it can be validated.
>
> As a nit, the repeated instances of "../header/" in the error message is an
> annoyance.
>
> Diagnostic message and code given below.
>
> thanks
> art
>
> ../header/../header/../header/../header/Stack.h: In member function
> ‘std::string Stack<T>::toString()’:
> ../header/../header/../header/../header/Stack.h:184:46: error: expected
> primary-expression before ‘.’ token
>   184 |       str << setw(3) << s.size() << ": " << T.toString();
>       |                                              ^
>
> # include <iomanip>
> # include <sstream>
>
> using namespace std;
> template <class T>
> class Stack {
>    string toString() {
>       stringstream str;
>       str << setw(3) << s.size() << ": " << T.toString();

T is of class type. You can't call a member function on a class. If you
want to call a static class function, write

  T::toString();

If you have an instance of type T, then calling toString() here should
work.
The error message doesn't really guide you towards the actual problem
(but it does show the correct location).
But I'm not a GCC developer - no idea how difficult it would be to
improve this.

Best regards,
Thomas

>       return str.str();
>    };
> };
>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 21:02 ` Thomas Bleher
@ 2023-11-09 21:07   ` Arthur Schwarz
  0 siblings, 0 replies; 8+ messages in thread
From: Arthur Schwarz @ 2023-11-09 21:07 UTC (permalink / raw)
  To: Thomas Bleher; +Cc: gcc-help

The issue is I do not want a static function. I could do this by using a 
static variable referencing the object 'this' pointer but, sigh, that 
means that there can be only one instance of T.

Well, resigned to ignominy, that's what I thought.

thanks

On 11/9/2023 1:02 PM, Thomas Bleher wrote:
> * Arthur Schwarz <home@slipbits.com> [2023-11-09 21:46]:
>> Is there any way to use a function passed as an argument to a template
>> (example below)? Couldn't the existence of the referenced function be
>> established durint instantiation (Stack<some class> obj)? I realize that
>> just doing analysis of the template that the existence of a referenced
>> function can't be determined, but during instantiation it can be validated.
>>
>> As a nit, the repeated instances of "../header/" in the error message is an
>> annoyance.
>>
>> Diagnostic message and code given below.
>>
>> thanks
>> art
>>
>> ../header/../header/../header/../header/Stack.h: In member function
>> ‘std::string Stack<T>::toString()’:
>> ../header/../header/../header/../header/Stack.h:184:46: error: expected
>> primary-expression before ‘.’ token
>>    184 |       str << setw(3) << s.size() << ": " << T.toString();
>>        |                                              ^
>>
>> # include <iomanip>
>> # include <sstream>
>>
>> using namespace std;
>> template <class T>
>> class Stack {
>>     string toString() {
>>        stringstream str;
>>        str << setw(3) << s.size() << ": " << T.toString();
> T is of class type. You can't call a member function on a class. If you
> want to call a static class function, write
>
>    T::toString();
>
> If you have an instance of type T, then calling toString() here should
> work.
> The error message doesn't really guide you towards the actual problem
> (but it does show the correct location).
> But I'm not a GCC developer - no idea how difficult it would be to
> improve this.
>
> Best regards,
> Thomas
>
>>        return str.str();
>>     };
>> };
>>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 20:46 Can you use a function reference passed in a template argument? Arthur Schwarz
  2023-11-09 21:02 ` Thomas Bleher
@ 2023-11-09 21:11 ` Jonathan Wakely
  2023-11-09 21:24   ` Arthur Schwarz
  1 sibling, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2023-11-09 21:11 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

On Thu, 9 Nov 2023 at 20:46, Arthur Schwarz <home@slipbits.com> wrote:
>
>
> Is there any way to use a function passed as an argument to a template
> (example below)? Couldn't the existence of the referenced function be
> established durint instantiation (Stack<some class> obj)? I realize that
> just doing analysis of the template that the existence of a referenced
> function can't be determined, but during instantiation it can be validated.

I have no idea what that code is trying to do. You're trying to call a
member function on a _type_ T.

And you said you want to call a function passed as an argument ... but
the template argument you pass is a type, not a function.


>
> As a nit, the repeated instances of "../header/" in the error message is
> an annoyance.

That looks like a problem with symlinks or your build system, not gcc's fault.

>
> Diagnostic message and code given below.
>
> thanks
> art
>
> ../header/../header/../header/../header/Stack.h: In member function
> ‘std::string Stack<T>::toString()’:
> ../header/../header/../header/../header/Stack.h:184:46: error: expected
> primary-expression before ‘.’ token
>    184 |       str << setw(3) << s.size() << ": " << T.toString();
>        |                                              ^
>
> # include <iomanip>
> # include <sstream>
>
> using namespace std;
> template <class T>
> class Stack {
>     string toString() {
>        stringstream str;
>        str << setw(3) << s.size() << ": " << T.toString();
>        return str.str();
>     };
> };
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 21:11 ` Jonathan Wakely
@ 2023-11-09 21:24   ` Arthur Schwarz
  2023-11-09 21:58     ` Jonathan Wakely
  0 siblings, 1 reply; 8+ messages in thread
From: Arthur Schwarz @ 2023-11-09 21:24 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help


On 11/9/2023 1:11 PM, Jonathan Wakely via Gcc-help wrote:
> On Thu, 9 Nov 2023 at 20:46, Arthur Schwarz <home@slipbits.com> wrote:
>>
>> Is there any way to use a function passed as an argument to a template
>> (example below)? Couldn't the existence of the referenced function be
>> established durint instantiation (Stack<some class> obj)? I realize that
>> just doing analysis of the template that the existence of a referenced
>> function can't be determined, but during instantiation it can be validated.
> I have no idea what that code is trying to do. You're trying to call a
> member function on a _type_ T.
As if I knew what I was trying to do.
>
> And you said you want to call a function passed as an argument ... but
> the template argument you pass is a type, not a function.
>
At the time of object instantiation the 'type' is a class and as a 
member of this
class there is a function. It is resolvable that when a class is used 
that to satisfy
the requirement that the template object is correct, the class must 
contain the
indicated function. If a passed class does not contain the indicated 
function,
then an error can be generated.

It looks like the determination of template instantiability is made when 
the
template is 'compiled', and at this time it is not possible to determine 
that
the referenced function, T.fun(), is available. This validation only 
becomes
possible during template instantiation, that is, when 
template_name<class_name>
is instantiated. To me the question then becomes does the standard require
that checking is not deferred until instantiation.

>> As a nit, the repeated instances of "../header/" in the error message is
>> an annoyance.
> That looks like a problem with symlinks or your build system, not gcc's fault.
>
>> Diagnostic message and code given below.
>>
>> thanks
>> art
>>
>> ../header/../header/../header/../header/Stack.h: In member function
>> ‘std::string Stack<T>::toString()’:
>> ../header/../header/../header/../header/Stack.h:184:46: error: expected
>> primary-expression before ‘.’ token
>>     184 |       str << setw(3) << s.size() << ": " << T.toString();
>>         |                                              ^
>>
>> # include <iomanip>
>> # include <sstream>
>>
>> using namespace std;
>> template <class T>
>> class Stack {
>>      string toString() {
>>         stringstream str;
>>         str << setw(3) << s.size() << ": " << T.toString();
>>         return str.str();
>>      };
>> };
>>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 21:24   ` Arthur Schwarz
@ 2023-11-09 21:58     ` Jonathan Wakely
  2023-11-09 22:00       ` Jonathan Wakely
  0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2023-11-09 21:58 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

On Thu, 9 Nov 2023 at 21:24, Arthur Schwarz <home@slipbits.com> wrote:
>
>
> On 11/9/2023 1:11 PM, Jonathan Wakely via Gcc-help wrote:
> > On Thu, 9 Nov 2023 at 20:46, Arthur Schwarz <home@slipbits.com> wrote:
> >>
> >> Is there any way to use a function passed as an argument to a template
> >> (example below)? Couldn't the existence of the referenced function be
> >> established durint instantiation (Stack<some class> obj)? I realize that
> >> just doing analysis of the template that the existence of a referenced
> >> function can't be determined, but during instantiation it can be validated.
> > I have no idea what that code is trying to do. You're trying to call a
> > member function on a _type_ T.
> As if I knew what I was trying to do.
> >
> > And you said you want to call a function passed as an argument ... but
> > the template argument you pass is a type, not a function.
> >
> At the time of object instantiation the 'type' is a class and as a
> member of this
> class there is a function. It is resolvable that when a class is used
> that to satisfy
> the requirement that the template object is correct, the class must
> contain the
> indicated function. If a passed class does not contain the indicated
> function,
> then an error can be generated.

No, you have a category error. You call a non-static member function
on an object, not on a type.

You could write T().toString() which would create a temporary object
of type T, and call the function on _that_. But you can't call a
non-static member function on a type. You need an object.

>
> It looks like the determination of template instantiability is made when
> the
> template is 'compiled', and at this time it is not possible to determine
> that
> the referenced function, T.fun(), is available.

T.fun() is not even valid C++ syntax, it's just nonsense. So the
problem has nothing to do with when the template is instantiated or
compiled. You're just writing something that isn't C++.

> This validation only
> becomes
> possible during template instantiation, that is, when
> template_name<class_name>
> is instantiated. To me the question then becomes does the standard require
> that checking is not deferred until instantiation.
>
> >> As a nit, the repeated instances of "../header/" in the error message is
> >> an annoyance.
> > That looks like a problem with symlinks or your build system, not gcc's fault.
> >
> >> Diagnostic message and code given below.
> >>
> >> thanks
> >> art
> >>
> >> ../header/../header/../header/../header/Stack.h: In member function
> >> ‘std::string Stack<T>::toString()’:
> >> ../header/../header/../header/../header/Stack.h:184:46: error: expected
> >> primary-expression before ‘.’ token
> >>     184 |       str << setw(3) << s.size() << ": " << T.toString();
> >>         |                                              ^
> >>
> >> # include <iomanip>
> >> # include <sstream>
> >>
> >> using namespace std;
> >> template <class T>
> >> class Stack {
> >>      string toString() {
> >>         stringstream str;
> >>         str << setw(3) << s.size() << ": " << T.toString();
> >>         return str.str();
> >>      };
> >> };
> >>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 21:58     ` Jonathan Wakely
@ 2023-11-09 22:00       ` Jonathan Wakely
  2023-11-09 22:10         ` Arthur Schwarz
  0 siblings, 1 reply; 8+ messages in thread
From: Jonathan Wakely @ 2023-11-09 22:00 UTC (permalink / raw)
  To: Arthur Schwarz; +Cc: gcc-help

On Thu, 9 Nov 2023 at 21:58, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>
> On Thu, 9 Nov 2023 at 21:24, Arthur Schwarz <home@slipbits.com> wrote:
> >
> >
> > On 11/9/2023 1:11 PM, Jonathan Wakely via Gcc-help wrote:
> > > On Thu, 9 Nov 2023 at 20:46, Arthur Schwarz <home@slipbits.com> wrote:
> > >>
> > >> Is there any way to use a function passed as an argument to a template
> > >> (example below)? Couldn't the existence of the referenced function be
> > >> established durint instantiation (Stack<some class> obj)? I realize that
> > >> just doing analysis of the template that the existence of a referenced
> > >> function can't be determined, but during instantiation it can be validated.
> > > I have no idea what that code is trying to do. You're trying to call a
> > > member function on a _type_ T.
> > As if I knew what I was trying to do.
> > >
> > > And you said you want to call a function passed as an argument ... but
> > > the template argument you pass is a type, not a function.
> > >
> > At the time of object instantiation the 'type' is a class and as a
> > member of this
> > class there is a function. It is resolvable that when a class is used
> > that to satisfy
> > the requirement that the template object is correct, the class must
> > contain the
> > indicated function. If a passed class does not contain the indicated
> > function,
> > then an error can be generated.
>
> No, you have a category error. You call a non-static member function
> on an object, not on a type.
>
> You could write T().toString() which would create a temporary object
> of type T, and call the function on _that_. But you can't call a
> non-static member function on a type. You need an object.
>
> >
> > It looks like the determination of template instantiability is made when
> > the
> > template is 'compiled', and at this time it is not possible to determine
> > that
> > the referenced function, T.fun(), is available.
>
> T.fun() is not even valid C++ syntax, it's just nonsense. So the
> problem has nothing to do with when the template is instantiated or
> compiled. You're just writing something that isn't C++.


To see that this is not about template instantiation, consider:

struct S {
  string toString() { return "S"; }
};

int main()
{
  std::cout << S.toString();
}

This is the same as what you tried to write, it uses a type S where an
object is required. It's not valid C++.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Can you use a function reference passed in a template argument?
  2023-11-09 22:00       ` Jonathan Wakely
@ 2023-11-09 22:10         ` Arthur Schwarz
  0 siblings, 0 replies; 8+ messages in thread
From: Arthur Schwarz @ 2023-11-09 22:10 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

Thanks. You have clearly explained both my errors and my inability to do 
what I want in the way I want. Being wise, I will change my mind, and if 
I really feel distraught, will attempt to do it another way.

On 11/9/2023 2:00 PM, Jonathan Wakely wrote:
> On Thu, 9 Nov 2023 at 21:58, Jonathan Wakely <jwakely.gcc@gmail.com> wrote:
>> On Thu, 9 Nov 2023 at 21:24, Arthur Schwarz <home@slipbits.com> wrote:
>>>
>>> On 11/9/2023 1:11 PM, Jonathan Wakely via Gcc-help wrote:
>>>> On Thu, 9 Nov 2023 at 20:46, Arthur Schwarz <home@slipbits.com> wrote:
>>>>> Is there any way to use a function passed as an argument to a template
>>>>> (example below)? Couldn't the existence of the referenced function be
>>>>> established durint instantiation (Stack<some class> obj)? I realize that
>>>>> just doing analysis of the template that the existence of a referenced
>>>>> function can't be determined, but during instantiation it can be validated.
>>>> I have no idea what that code is trying to do. You're trying to call a
>>>> member function on a _type_ T.
>>> As if I knew what I was trying to do.
>>>> And you said you want to call a function passed as an argument ... but
>>>> the template argument you pass is a type, not a function.
>>>>
>>> At the time of object instantiation the 'type' is a class and as a
>>> member of this
>>> class there is a function. It is resolvable that when a class is used
>>> that to satisfy
>>> the requirement that the template object is correct, the class must
>>> contain the
>>> indicated function. If a passed class does not contain the indicated
>>> function,
>>> then an error can be generated.
>> No, you have a category error. You call a non-static member function
>> on an object, not on a type.
>>
>> You could write T().toString() which would create a temporary object
>> of type T, and call the function on _that_. But you can't call a
>> non-static member function on a type. You need an object.

Wouldn't work. The values to be returned by toString() are the state 
variables for
the current object. New object. New state variables. (But it is 
interesting).

>>
>>> It looks like the determination of template instantiability is made when
>>> the
>>> template is 'compiled', and at this time it is not possible to determine
>>> that
>>> the referenced function, T.fun(), is available.
>> T.fun() is not even valid C++ syntax, it's just nonsense. So the
>> problem has nothing to do with when the template is instantiated or
>> compiled. You're just writing something that isn't C++.
>
> To see that this is not about template instantiation, consider:
>
> struct S {
>    string toString() { return "S"; }
> };
>
> int main()
> {
>    std::cout << S.toString();
> }
>
> This is the same as what you tried to write, it uses a type S where an
> object is required. It's not valid C++.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-11-09 22:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-09 20:46 Can you use a function reference passed in a template argument? Arthur Schwarz
2023-11-09 21:02 ` Thomas Bleher
2023-11-09 21:07   ` Arthur Schwarz
2023-11-09 21:11 ` Jonathan Wakely
2023-11-09 21:24   ` Arthur Schwarz
2023-11-09 21:58     ` Jonathan Wakely
2023-11-09 22:00       ` Jonathan Wakely
2023-11-09 22:10         ` Arthur Schwarz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).