472,802 Members | 1,279 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,802 software developers and data experts.

Template argument deduction and conversion operators.

Here is a piece of code:

#include <memory>
using namespace std;

template< typename SomeType >
void f(auto_ptr_ref< SomeType >)
{
}

int __cdecl main(int,char*[])
{
auto_ptr< int > a;
f( a ); // 1: could not deduce template argument
f< int >( a ); // 2: OK
return 0;
}

My question is if there is a standard way to force the compiler to
compile line 1 as it compiles line 2, i.e. to deduce template arguments
in a way that will allow conversion operators to be called if
necessary.

Jul 23 '05 #1
3 1851
Bi****@abv.bg wrote:
Here is a piece of code:

#include <memory>
using namespace std;

template< typename SomeType >
void f(auto_ptr_ref< SomeType >)
{
}

int __cdecl main(int,char*[])
{
auto_ptr< int > a;
f( a ); // 1: could not deduce template argument
f< int >( a ); // 2: OK
return 0;
}

My question is if there is a standard way to force the compiler to
compile line 1 as it compiles line 2, i.e. to deduce template arguments
in a way that will allow conversion operators to be called if
necessary.


No. The rule is that the conversions are not applied when trying to
deduce template arguments. There are several (although quite a few)
context in which the argument is deducible, and none of them involve
conversions, IIRC.

V
Jul 23 '05 #2
Bi****@abv.bg wrote:
Here is a piece of code:

#include <memory>
using namespace std;

template< typename SomeType >
void f(auto_ptr_ref< SomeType >)
{
}

int __cdecl main(int,char*[])
{
auto_ptr< int > a;
f( a ); // 1: could not deduce template argument
f< int >( a ); // 2: OK
return 0;
}

My question is if there is a standard way to force the compiler to
compile line 1 as it compiles line 2, i.e. to deduce template arguments
in a way that will allow conversion operators to be called if
necessary.


Of course not. We can even forget about the rules of template argument
deduction. It is impossible for a more generic reason.

The conversion operator that converts 'auto_ptr<T>' to
'auto_ptr<T>::auto_ptr_ref<U>' is itself a template with its own
independent parameter (note 'U'). This means that the above conversion
is infinitely ambiguous. How do you expect the compiler to treat the
line 1? As

f<int>(a.operator auto_ptr_ref<int>());

? Why not

f<double>(a.operator auto_ptr_ref<double>());

or

f<char>(a.operator auto_ptr_ref<char>());

Note, once again, that the parameter of the conversion operator template
is not related in any way to the parameter of the entire 'auto_ptr<>'
class template, which means that from the compiler's point of view the
first variant (with 'int') is in no way better than any other variant.
(It's like solving an equation with two unknowns. In general case it has
infinite number of solutions and no one is better than the others.)

In order to resolve the ambiguity in one way of another you have to
provide compiler with extra information. On way to do it is to specify
the 'f' template argument explicitly and let the compiler to deduce the
argument for the conversion operator

f<int>(a);

Another way would be to perform explicit type conversion and let the
compiler to deduce 'f's template argument

f((auto_ptr<int>::auto_ptr_ref<int>) a);

The last example is provided for purely illustrational purposes, it will
not work in practice because 'auto_ptr_ref' is not a public member of
'auto_ptr'.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #3
Yes, you are right that in the case with auto_ptr and auto_ptr_ref the
call is ambiguous! And all this is due to the templated conversion
operator.
Now, could you consider my previous question in the case where the
conversion operator is not templated as in the code that follows. My
question was: is it possible to deduce templat*e arguments in a way
that will allow conversion operators to be called i*f necessary?

template< typename SomeType >
class RW;

template< typename SomeType >
class RWRef
{
private:
RWRef( RW< SomeType > const* const ){ }
friend RW< SomeType >;
};

template< typename SomeType >
class RW
{
public:
RW( ) { }

operator RWRef< SomeType >( ) const { return RWRef< SomeType >( this
); }
};

template< typename SomeType >
void f
(
RWRef< SomeType >
)
{
}

int main
(
int,
char*[]
)
{
RW< int > a;
f( a );

return 0;
}

Jul 23 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: bartek | last post by:
Please consider the following scenario below (sketch of). There are two templates defined: A and B, both with mutual conversion operators defined. Also, there's a free function template...
4
by: Dave | last post by:
Hello all, Consider this template: template <typename T> void foo(T bar) {...} Here are three ways to instantiate this: 1.
5
by: Steven T. Hatton | last post by:
The comperable operator*() to that shown here works for a non-template class: template <typename T> inline Vector3<T> operator*(const Vector3<T>& v, const T& n) { Vector3<T> t(v); return t *=...
14
by: Bart Samwel | last post by:
Hi everybody, I would really like some help explaining this apparent discrepancy, because I really don't get it. Here is the snippet: void foo(int&); void foo(int const&); ...
5
by: Vijai Kalyan | last post by:
Hello, I have come back to C++ after a couple of years with Java so I am quite rusty and this question may seem poor: My platform is Windows XP with MSVC 7.1. I have a class with a...
4
by: George | last post by:
Dear All, I'm compiling the code below with IBM's xlC 6.0 and get the message, "rmspace.cpp", line 34.48: 1540-0298 (S) Template argument deduction cannot be performed using the function...
2
by: coolpint | last post by:
Can anyone kindly provide an explanation as to why the compiler does not "see" the function template in the contrieved code below? I think the argument deduction fails but can't figure out...
3
by: =?gb2312?B?wfXquw==?= | last post by:
Hi, folks, I'm running into a question as below: template<typename T> class A { private: T _a; public: A(T t): _a(t) { }
3
by: Fei Liu | last post by:
Hello, We all know that a template function can automatically deduce its parameter type and instantiate, e.g. template <tpyename T> void func(T a); func(0.f); This will cause func<floatto...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Sept 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.