How do I initialize const int with int?

D

DeMarcus

Hi!

I'm stuck in a template. Can anyone see what I'm doing wrong?

template<typename T>
class Foo
{
public:
Foo( T t ) {}
};

class Bar
{
public:
template<typename T>
void add( Foo<T>& foo, T t ) {}
};

int main()
{
Foo<const int> foo( 47 );
Bar b;
b.add( foo, 11 ); // ERROR!
// "No matching function for call to Bar::add(Foo<const int>&, int)"
}

I want the function be Bar::add(Foo<const int>&, const int)
How can I achieve that?


Thanks!
Daniel
 
A

Alf P. Steinbach

* DeMarcus:
Hi!

I'm stuck in a template. Can anyone see what I'm doing wrong?

template<typename T>
class Foo
{
public:
Foo( T t ) {}
};

class Bar
{
public:
template<typename T>
void add( Foo<T>& foo, T t ) {}
};

int main()
{
Foo<const int> foo( 47 );
Bar b;
b.add( foo, 11 ); // ERROR!
// "No matching function for call to Bar::add(Foo<const int>&, int)"
}

I want the function be Bar::add(Foo<const int>&, const int)
How can I achieve that?

Background: a top level const for a formal argument is not part of the routine's
signature. The matching rules are complicated and I won't pretend to understand
what exactly is going on (sitting down with the Holy Standard would presumably
clarify that in just a matter of half an hour or so, but with no practical
significance). But I very much suspect that it's that top-level const rule.

First I simply tried ...


template< typename T >
void add( Foo<T>& foo, T const& t ) {}


.... but that didn't work (I guess James Kanze can explain why), so then I did:


<code>
template<typename T>
class Foo
{
public:
Foo( T ) {}
};

class Bar
{
private:
template<typename T>
void do_add( Foo<T>&, T ) {}

public:
template<typename T>
void add( Foo<T const>& foo, T t ) { do_add<T const>( foo, t ); }

template<typename T>
void add( Foo<T>& foo, T t ) { do_add<T>( foo, t ); }
};

int main()
{
Foo<int const> foo( 47 );
Foo<int> foo2( 123 );
Bar b;
b.add( foo, 11 );
b.add( foo2, 12 );
}
</code>




Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* Leigh Johnston:
Well T is still ambiguous (can be const int or int) even with the const&
addition.

Yeah, that's what both compilers I tried said, but I won't pretend to understand
why they don't find exact match. I guess I could, once long ago. But.

Anyways, inspired by your solution else-thread, which was much smarter than my
individual cases, a reusable solution, the amazing ...

.... DontMatch<TM> class!


<code>
template<typename T>
class Foo
{
public:
Foo( T ) {}
};

template< typename TM >
struct DontMatch { typedef TM Type; };

class Bar
{
public:
template<typename T>
void add( Foo<T>&, typename DontMatch<T>::Type ) {}
};

int main()
{
Foo<int const> foo( 47 );
Foo<int> foo2( 123 );
Bar b;
b.add( foo, 11 );
b.add( foo2, 12 );
}
</code>


Cheers,

- Alf
 
D

DeMarcus

Alf said:
* Leigh Johnston:

Yeah, that's what both compilers I tried said, but I won't pretend to
understand why they don't find exact match. I guess I could, once long
ago. But.

Anyways, inspired by your solution else-thread, which was much smarter
than my individual cases, a reusable solution, the amazing ...

... DontMatch<TM> class!


<code>
template<typename T>
class Foo
{
public:
Foo( T ) {}
};

template< typename TM >
struct DontMatch { typedef TM Type; };

class Bar
{
public:
template<typename T>
void add( Foo<T>&, typename DontMatch<T>::Type ) {}
};

int main()
{
Foo<int const> foo( 47 );
Foo<int> foo2( 123 );
Bar b;
b.add( foo, 11 );
b.add( foo2, 12 );
}
</code>


Cheers,

- Alf

Thanks for your help!
 
B

Bart van Ingen Schenau

* Leigh Johnston:





Yeah, that's what both compilers I tried said, but I won't pretend to understand
why they don't find exact match. I guess I could, once long ago. But.

The problem is that the template argument deduction is done for each
function parameter separately.
The first parameter deduces that T must be 'const int.'
The second parameter deduces that T must be 'int.'
As the two independent deductions do not yield the same result, the
template argument deduction is ambiguous.
Anyways, inspired by your solution else-thread, which was much smarter than my
individual cases, a reusable solution, the amazing ...

... DontMatch<TM> class!

<code>
template<typename T>
class Foo
{
public:
    Foo( T ) {}

};

template< typename TM >
struct DontMatch { typedef TM Type; };

class Bar
{
public:
    template<typename T>
    void add( Foo<T>&, typename DontMatch<T>::Type ) {}

This works, because here, T in the second argument has been used in a
way that it can not be deduced. Therefor, the second argument is not
considered for the template argument deduction and there are no
ambiguities possible any more.
};

int main()
{
    Foo<int const>   foo( 47 );
    Foo<int>         foo2( 123 );
    Bar b;
    b.add( foo, 11 );
    b.add( foo2, 12 );}

</code>

Cheers,

- Alf

Bart v Ingen Schenau
 
D

DeMarcus

Alf said:
* Leigh Johnston:

Yeah, that's what both compilers I tried said, but I won't pretend to
understand why they don't find exact match. I guess I could, once long
ago. But.

Anyways, inspired by your solution else-thread, which was much smarter
than my individual cases, a reusable solution, the amazing ...

... DontMatch<TM> class!


<code>
template<typename T>
class Foo
{
public:
Foo( T ) {}
};

template< typename TM >
struct DontMatch { typedef TM Type; };

class Bar
{
public:
template<typename T>
void add( Foo<T>&, typename DontMatch<T>::Type ) {}
};

int main()
{
Foo<int const> foo( 47 );
Foo<int> foo2( 123 );
Bar b;
b.add( foo, 11 );
b.add( foo2, 12 );
}
</code>


Cheers,

- Alf

Which is the preferred way of solving this problem? Alf's DontMatch
solution or Leigh's solution below? (taken from a previous post)

template<typename T>
void add( Foo<T>& foo, typename Foo<T>::value_type t ) {}

Both work of course, but what would an STL guru write?

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top