Re: Template deduction: can I encourage compiler to deduce "const"?
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.