Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Template deduction: can I encourage compiler to deduce "const"?

Reply
Thread Tools

Template deduction: can I encourage compiler to deduce "const"?

 
 
Chris Stankevitz
Guest
Posts: n/a
 
      03-03-2013
Hello,

Please consider the following example. In the last two lines of
"main" I specify the first template argument. In particular, I
specify that the arguments are "const". Is there any way I can get
the compiler to deduce this so that I do not need to specify it?

The compiler appears to have "trouble" only when the arguments are
anonymous.

FYI I am using gcc 4.6.3.

Thank you,

Chris

// ==========

struct TSObject {};

struct TSVisitor
{
template<
class TAMutableOrConstFunctor,
class TAMutableOrConstObject>
void Visit(
TAMutableOrConstFunctor& Functor,
TAMutableOrConstObject& Object)
{
Functor(Object);
}
};

struct TSFunctorMM { void operator()( TSObject& Object)
{} };
struct TSFunctorMC { void operator()( TSObject& Object) const
{} };
struct TSFunctorCM { void operator()(const TSObject& Object)
{} };
struct TSFunctorCC { void operator()(const TSObject& Object) const
{} };

int main()
{
TSObject Object;

TSVisitor Visitor;

TSFunctorMM FunctorMM;
TSFunctorMC FunctorMC;
TSFunctorCM FunctorCM;
TSFunctorCC FunctorCC;

Visitor.Visit(FunctorMM, Object);
Visitor.Visit(FunctorMC, Object);
Visitor.Visit(FunctorCM, Object);
Visitor.Visit(FunctorCC, Object);

Visitor.Visit<const TSFunctorMC>(TSFunctorMC(), Object);
Visitor.Visit<const TSFunctorCC>(TSFunctorCC(), Object);

return 0;
}
 
Reply With Quote
 
 
 
 
Bart van Ingen Schenau
Guest
Posts: n/a
 
      03-03-2013
On Sun, 03 Mar 2013 00:12:17 -0800, Chris Stankevitz wrote:

> Hello,
>
> Please consider the following example. In the last two lines of "main"
> I specify the first template argument. In particular, I specify that
> the arguments are "const". Is there any way I can get the compiler to
> deduce this so that I do not need to specify it?
>
> The compiler appears to have "trouble" only when the arguments are
> anonymous.


The compiler has no trouble at all in deducing the template parameters.
The trouble starts at the next step, where the compiler finds that you
try to bind an rvalue to a non-const lvalue reference and it balks at
that.

The two solutions that I can think of to resolve this issue are
1. Pass the functor by value (con: changes to a state-full functor will
not be visible in the caller)
2. Pass the functor by rvalue reference (con: your compiler has to
support it.)

>
> FYI I am using gcc 4.6.3.
>
> Thank you,
>
> Chris
>

Bart v Ingen Schenau
 
Reply With Quote
 
 
 
 
jz bnk
Guest
Posts: n/a
 
      03-03-2013
On Sunday, March 3, 2013 1:12:17 AM UTC-7, Chris Stankevitz wrote:
> Hello,
>
>
>
> Please consider the following example. In the last two lines of
>
> "main" I specify the first template argument. In particular, I
>
> specify that the arguments are "const". Is there any way I can get
>
> the compiler to deduce this so that I do not need to specify it?
>
>
>
> The compiler appears to have "trouble" only when the arguments are
>
> anonymous.


Possibly – however, is there some reason why you can't use rvalue references
here? Search “universal reference” if you're not familiar with that idiom
(don't particularly like that name myself, but it's what we've got...
 
Reply With Quote
 
Chris Stankevitz
Guest
Posts: n/a
 
      03-03-2013
On Mar 3, 12:34*am, jz bnk <iwg.mo...@gmail.com> wrote:
> Possibly – however, is there some reason why you can't use rvalue references
> here? *Search “universal reference”


Thank you. I have never used a universal reference but I know what
they are and can use one here.

Thank you,

Chris

 
Reply With Quote
 
Chris Stankevitz
Guest
Posts: n/a
 
      03-03-2013
On Mar 3, 12:34*am, Bart van Ingen Schenau
<b...@ingen.ddns.info.invalid> wrote:
> The compiler has no trouble at all in deducing the template parameters.
> The trouble starts at the next step, where the compiler finds that you
> try to bind an rvalue to a non-const lvalue reference


Hello,

Thank you for your reply. I think you are trying to make these
points:

1. The compiler is presented with an rvalue and the opportunity to
"deduce" that rvalue into
a) a mutable lvalue reference
or
b) a const lvalue reference

2. The compiler is choosing (a).

3. (a) is a reasonable deduction for the compiler to make.

4. If I want (b) I will need to use explicit template arguments or
universal references.

Thank you,

Chris
 
Reply With Quote
 
SG
Guest
Posts: n/a
 
      03-03-2013
On Mar 3, 9:12*am, Chris Stankevitz wrote:
> Hello,
>
> Please consider the following example. *In the last two lines of
> "main" I specify the first template argument. *In particular, I
> specify that the arguments are "const". *Is there any way I can get
> the compiler to deduce this so that I do not need to specify it?


Why? What problem are you trying to solve?

> // ==========
>
> struct TSObject {};
>
> struct TSVisitor
> {
> * template<
> * * class TAMutableOrConstFunctor,
> * * class TAMutableOrConstObject>
> * void Visit(
> * * TAMutableOrConstFunctor& Functor,
> * * TAMutableOrConstObject& Object)
> * {
> * * Functor(Object);
> * }
> };
>
> struct TSFunctorMM { void operator()( * * *TSObject& Object)
> {} };
> struct TSFunctorMC { void operator()( * * *TSObject& Object) const
> {} };
> struct TSFunctorCM { void operator()(const TSObject& Object)
> {} };
> struct TSFunctorCC { void operator()(const TSObject& Object) const
> {} };
>
> int main()
> {
> * TSObject Object;
>
> * TSVisitor Visitor;
>
> * TSFunctorMM FunctorMM;
> * TSFunctorMC FunctorMC;
> * TSFunctorCM FunctorCM;
> * TSFunctorCC FunctorCC;
>
> * Visitor.Visit(FunctorMM, Object);
> * Visitor.Visit(FunctorMC, Object);
> * Visitor.Visit(FunctorCM, Object);
> * Visitor.Visit(FunctorCC, Object);
>
> * Visitor.Visit<const TSFunctorMC>(TSFunctorMC(), Object);
> * Visitor.Visit<const TSFunctorCC>(TSFunctorCC(), Object);


I understand that you want this to "work" without having to specify
such a template parameter. But what does "work" actually mean here?
You should be more specific as to what kind of behaviour you are
shooting for.

Here's an idea:

struct TSVisitor
{
* template<
* * class TAMutableOrConstFunctor,
* * class TAMutableOrConstObject >
* void Visit(
* * TAMutableOrConstFunctor && Functor,
* * TAMutableOrConstObject && Object )
* {
std::forward<const TAMutableOrConstFunctor>(Functor)(
std::forward<const TAMutableOrConstObject>(Object)
);
* }
};

forward<const T>(param) allows non-const lvalues to be modified while
rvalues are always forwarded as const. If you don't want to restrict
access to rvalues like that you can simply remove "const":
forward<T>(param). I just added the const here because it looks like
you don't want temporaries to be mutable. But removing it might lead
to more efficient code since you can possibly leverage move-semantics-
like optimizations.
 
Reply With Quote
 
Chris Stankevitz
Guest
Posts: n/a
 
      03-03-2013
On Mar 3, 1:32*am, SG <s.gesem...@gmail.com> wrote:
> Why? What problem are you trying to solve?


My short term goal:

Get the original-post code to compile without specifying the template
argument. Your universal reference trick fixed this, thank you for
that help. However, I'm not sure why you specify "const" in the
template argument to std::forward. I'm not sure why you wouldn't
either. I just don't know about that. It seems since I sometimes
want to treat the universal reference as an lvalue that I would not
type 'const' anywhere.

My medium term goal:

I have a functor and an object. The functor wants to be passed some
parameter that is derived from the object. A "third party
intermediary" is
1. taking the functor and object
2. using the object to produce yet another "third party object"
3. pass the derived "third party object" to the functor

The difficulty is that the third party doesn't know if the object
should be a const reference or a mutable reference. And it doesn't
know whether the functor should be a const reference or a mutable
reference. I'm having trouble incorporating this concept into my
simple original post example. So you can look at...

My medium long term goal:

To statically store and retrieve the characteristics of a class's
members. For more info and a link to the github source you can jump
in to the thread here:

http://lists.boost.org/boost-users/2013/03/77972.php

My long term goals:

to make money, remodel my kitchen, make my wife happy, make me happy.
That's what all this really boils down to. My selfish desire to be
happy.

Thanks again,

Chris

===
 
Reply With Quote
 
Bart van Ingen Schenau
Guest
Posts: n/a
 
      03-04-2013
On Sun, 03 Mar 2013 01:14:40 -0800, Chris Stankevitz wrote:

> On Mar 3, 12:34Â*am, Bart van Ingen Schenau
> <b...@ingen.ddns.info.invalid> wrote:
>> The compiler has no trouble at all in deducing the template parameters.
>> The trouble starts at the next step, where the compiler finds that you
>> try to bind an rvalue to a non-const lvalue reference

>
> Hello,
>
> Thank you for your reply. I think you are trying to make these points:
>
> 1. The compiler is presented with an rvalue and the opportunity to
> "deduce" that rvalue into
> a) a mutable lvalue reference
> or
> b) a const lvalue reference


Actually, the deduction process is slightly different.
- You have a function taking a TAFunctor& (with TAFunctor a template
parameter). As the function parameter is of reference type, the deduction
is done for the referenced type (TAFunctor).
- In the call, the function is provided with a value of TSFunctorMC
- Deduction is straightforward: TAFunctor is deduced as TSFunctorMC
- Deduction succeeds, so there is no reason to try additional options
(such as adding const-qualification or trying base/derived classes)

The problem you are encountering is that a rvalue of type T is itself
_not_ const qualified.

>
> 4. If I want (b) I will need to use explicit template arguments or
> universal references.


That is right. For the use-case you described in another post in the
thread, a universal reference seems the most appropriate choice.

>
> Thank you,
>
> Chris


Bart v Ingen Schenau
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
r H2 deduce deduce template argument of a template class inheritingfrom a non template base? nguillot C++ 5 03-08-2009 05:56 PM
Deduce function template argument Ed C++ 1 08-14-2008 08:13 PM
template function argument deduce George2 C++ 0 03-11-2008 12:39 PM
"could not deduce template argument" error gretean@comcast.net C++ 7 11-10-2006 03:03 PM
Forcing all function template parameters to deduce the same type Dan Krantz C++ 4 06-13-2006 02:28 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57