Connecting Tech Pros Worldwide Forums | Help | Site Map

conversion constructor

Alexander Stippler
Guest
 
Posts: n/a
#1: Oct 26 '05
hi,

the following does not work. I do not understand why, since it works
if I replace line marked by (1) with the line below ((2)). Compiling
with gcc4.0 results in "error: conversion from 'Two<int>' to non-scalar
type 'One<int>' requested". Has somebody an explanation for me?


template <typename T>
struct Convert
{
typedef T Type;
};

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

template <typename I>
One(const typename Convert<I>::Type &rhs) {} // (1)
// One(const I &rhs) {} // (2)
};

template <typename S>
class Two
{
};

int
main()
{
One<int> y = Two<int>();
}


If I replace the constructor call in main() by an explicit call, it
works again with both versions. I know the difference of the two calls(
think so), but I cannot explain the different result.

regards,
Alex

Victor Bazarov
Guest
 
Posts: n/a
#2: Oct 26 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> the following does not work. I do not understand why, since it works
> if I replace line marked by (1) with the line below ((2)). Compiling
> with gcc4.0 results in "error: conversion from 'Two<int>' to non-scalar
> type 'One<int>' requested". Has somebody an explanation for me?
>
>
> template <typename T>
> struct Convert
> {
> typedef T Type;
> };
>
> template <typename T>
> class One
> {
> public:
> One() {}
>
> template <typename I>
> One(const typename Convert<I>::Type &rhs) {} // (1)
> // One(const I &rhs) {} // (2)
> };
>
> template <typename S>
> class Two
> {
> };
>
> int
> main()
> {
> One<int> y = Two<int>();[/color]

So, let's try to see what happens here. If you use the (2), your 'I' is
anything, right (the c-tor is a template)? So, you declare 'One<T>' to
be constructible from any type through a const reference. It is also
constructible from another 'One<T>', through a copy constructor defined
by the compiler for you. The line above is, in fact the same as

typedef One<int> oi;

oi y( static_cast<oi>(Two<int>()) );

IOW, it constructs a temporary object of type Two<int>, then uses the user-
defined converstion to construct another temporary of One<int>, then copy-
constructs 'y' from the latter temporary. Then all temporaries are blown
away.

Now, what happens if you introduce Convert<I> there. You have the same
form

oi y( static_cast<oi>(Two<int>()) );

but now, how can 'static_cast' do its job? There is no conversion from
Two<int> to One<int>, only from Convert<???>::Type, given that ??? is
somehow figured out. For constructors, the template argument can _only_
be figured out from the type of the argument itself, not from a member of
some other template. What you're asking from the compiler is to figure out
what 'I' is if the argument to the constructor is 'Two<int>'. There is no
straight-forward, unambiguous, way to figure that out.
[color=blue]
> }
>
>
> If I replace the constructor call in main() by an explicit call,[/color]

An explicit call to *what*? To some function?
[color=blue]
> it
> works again with both versions. I know the difference of the two calls(
> think so), but I cannot explain the different result.[/color]

The contexts for _deducing_ template arguments from a function call are much
more flexible than that for a constructor.

V
mlimber
Guest
 
Posts: n/a
#3: Oct 26 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> hi,
>
> the following does not work. I do not understand why, since it works
> if I replace line marked by (1) with the line below ((2)). Compiling
> with gcc4.0 results in "error: conversion from 'Two<int>' to non-scalar
> type 'One<int>' requested". Has somebody an explanation for me?
>
>
> template <typename T>
> struct Convert
> {
> typedef T Type;
> };
>
> template <typename T>
> class One
> {
> public:
> One() {}
>
> template <typename I>
> One(const typename Convert<I>::Type &rhs) {} // (1)
> // One(const I &rhs) {} // (2)
> };
>
> template <typename S>
> class Two
> {
> };
>
> int
> main()
> {
> One<int> y = Two<int>();[/color]

Try:

One<int> y( Two<int>() );
[color=blue]
> }
>
>
> If I replace the constructor call in main() by an explicit call, it
> works again with both versions. I know the difference of the two calls(
> think so), but I cannot explain the different result.
>
> regards,
> Alex[/color]

Cheers! --M

mlimber
Guest
 
Posts: n/a
#4: Oct 26 '05

re: conversion constructor



mlimber wrote:[color=blue]
> Alexander Stippler wrote:[/color]
[snip][color=blue][color=green]
> > int
> > main()
> > {
> > One<int> y = Two<int>();[/color]
>
> Try:
>
> One<int> y( Two<int>() );
>[color=green]
> > }
> >
> >
> > If I replace the constructor call in main() by an explicit call, it
> > works again with both versions. I know the difference of the two calls(
> > think so), but I cannot explain the different result.[/color][/color]

Oh, right. You knew that. Well, it's probably because the compiler
doesn't do a conversion lookup by instantiating another template. I'm
sure one of the language lawyers around here can cite the paragraph of
the standard for you.

Cheers! --M

Alexander Stippler
Guest
 
Posts: n/a
#5: Oct 26 '05

re: conversion constructor


In <hYO7f.43297$Tf5.38036@newsread1.mlpsca01.us.to.ve rio.net> Victor
Bazarov wrote:[color=blue]
> Alexander Stippler wrote:[color=green]
>> the following does not work. I do not understand why, since it works
>> if I replace line marked by (1) with the line below ((2)). Compiling
>> with gcc4.0 results in "error: conversion from 'Two<int>' to non-
>> scalar type 'One<int>' requested". Has somebody an explanation for
>> me? template <typename T> struct Convert {
>> typedef T Type;
>> };
>>
>> template <typename T>
>> class One
>> {
>> public:
>> One() {}
>>
>> template <typename I>
>> One(const typename Convert<I>::Type &rhs) {} // (1)
>> // One(const I &rhs) {} // (2)
>> };
>>
>> template <typename S>
>> class Two
>> {
>> };
>>
>> int
>> main()
>> {
>> One<int> y = Two<int>();[/color]
>
> So, let's try to see what happens here. If you use the (2), your 'I'
> is anything, right (the c-tor is a template)? So, you declare
> 'One<T>' to be constructible from any type through a const reference.
> It is also constructible from another 'One<T>', through a copy
> constructor defined by the compiler for you. The line above is, in
> fact the same as
>
> typedef One<int> oi;
>
> oi y( static_cast<oi>(Two<int>()) );
>
> IOW, it constructs a temporary object of type Two<int>, then uses the
> user- defined converstion to construct another temporary of One<int>,
> then copy- constructs 'y' from the latter temporary. Then all
> temporaries are blown away.
>
> Now, what happens if you introduce Convert<I> there. You have the
> same form
>
> oi y( static_cast<oi>(Two<int>()) );
>
> but now, how can 'static_cast' do its job? There is no conversion
> from Two<int> to One<int>, only from Convert<???>::Type, given that ???
> is somehow figured out. For constructors, the template argument can _
> only_ be figured out from the type of the argument itself, not from a
> member of some other template. What you're asking from the compiler
> is to figure out what 'I' is if the argument to the constructor is
> 'Two<int>'. There is no straight-forward, unambiguous, way to figure
> that out.
>[color=green]
>> }
>>
>>
>> If I replace the constructor call in main() by an explicit call,[/color]
>
> An explicit call to *what*? To some function?[/color]


with explicit call I meant
One<int> y(Two<int>());
instead of
One<int> y = Two<int>();
with regard to the keyword 'explicit'.
And I still do not understand why the first works, whereas the second
doesn't.
[color=blue]
>[color=green]
>> it works again with both versions. I know the difference of the two
>> calls( think so), but I cannot explain the different result.[/color]
>
> The contexts for _deducing_ template arguments from a function call
> are much more flexible than that for a constructor.
>
> V
>[/color]

Alex
Victor Bazarov
Guest
 
Posts: n/a
#6: Oct 26 '05

re: conversion constructor


mlimber wrote:[color=blue]
> [...]
> Try:
>
> One<int> y( Two<int>() );[/color]

Ahem... Isn't it a function declaration?
Victor Bazarov
Guest
 
Posts: n/a
#7: Oct 26 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> [..]
> with explicit call I meant
> One<int> y(Two<int>());
> instead of
> One<int> y = Two<int>();
> with regard to the keyword 'explicit'.
> And I still do not understand why the first works, whereas the second
> doesn't.[/color]

Try accessing any members of "y" now :-)

V
Alexander Stippler
Guest
 
Posts: n/a
#8: Oct 26 '05

re: conversion constructor


In <TeP7f.43299$Tf5.7990@newsread1.mlpsca01.us.to.ver io.net> Victor
Bazarov wrote:[color=blue]
> Alexander Stippler wrote:[color=green]
>> [..]
>> with explicit call I meant
>> One<int> y(Two<int>());
>> instead of
>> One<int> y = Two<int>();
>> with regard to the keyword 'explicit'.
>> And I still do not understand why the first works, whereas the second
>> doesn't.[/color]
>
> Try accessing any members of "y" now :-)[/color]

Oh yes, I fell into this trap quite often :-((. So the solution I wanted
is not realizable.
What I originally wanted was some SFINAE construct for a constructor. Is
this somehow possible
without operating with a return value? I have the following:

template <typename T>
class A
{
public:
template <typename S>
A(const B<S> &rhs);
};

I have several instantiations of S and would like to allow all but one.
That's the reason for this
::Type construction which would then not be defined for this special type. Is there a way to realize
this concept?

Alex
mlimber
Guest
 
Posts: n/a
#9: Oct 26 '05

re: conversion constructor



Victor Bazarov wrote:[color=blue]
> mlimber wrote:[color=green]
> > [...]
> > Try:
> >
> > One<int> y( Two<int>() );[/color]
>
> Ahem... Isn't it a function declaration?[/color]

Oops! Good catch.

M

Victor Bazarov
Guest
 
Posts: n/a
#10: Oct 26 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> What I originally wanted was some SFINAE construct for a constructor. Is
> this somehow possible
> without operating with a return value? I have the following:
>
> template <typename T>
> class A
> {
> public:
> template <typename S>
> A(const B<S> &rhs);
> };
>
> I have several instantiations of S and would like to allow all but one.
> That's the reason for this
> ::Type construction which would then not be defined for this special type. Is there a way to realize
> this concept?[/color]

Let me get this straight... You're trying to allow construction from all
B<S> except some specific B<SS>, right? SFINAE is a "selection" mechanism
that allows to "fall back" onto some generic solution instead of another
particular one. Is that what you want? What would be that generic
solution? Or do you, in fact, need to prohibit conversion of that B<SS>
into A<T>, for all T, but for a particular SS? And you need this in
compile-time, correct?

V
Alexander Stippler
Guest
 
Posts: n/a
#11: Oct 26 '05

re: conversion constructor


In <v6Q7f.43343$Tf5.16429@newsread1.mlpsca01.us.to.ve rio.net> Victor
Bazarov wrote:[color=blue]
> Alexander Stippler wrote:[color=green]
>> What I originally wanted was some SFINAE construct for a constructor.
>> Is this somehow possible without operating with a return value? I
>> have the following: template <typename T> class A {
>> public:
>> template <typename S>
>> A(const B<S> &rhs);
>> };
>>
>> I have several instantiations of S and would like to allow all but
>> one. That's the reason for this
>> ::Type construction which would then not be defined for this special
>> ::type. Is there a way to realize
>> this concept?[/color]
>
> Let me get this straight... You're trying to allow construction from
> all B<S> except some specific B<SS>, right? SFINAE is a "selection"
> mechanism that allows to "fall back" onto some generic solution
> instead of another particular one. Is that what you want? What would
> be that generic solution?[/color]
[color=blue]
> Or do you, in fact, need to prohibit
> conversion of that B<SS> into A<T>, for all T, but for a particular SS?
> And you need this in compile-time, correct?
>[/color]

Sorry for being unprecise. That's it, your second guess is absolutely
what I want. The compiler shall not consider the constructor above for
one specific SS. But how to realize?

Alex
Victor Bazarov
Guest
 
Posts: n/a
#12: Oct 26 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> In <v6Q7f.43343$Tf5.16429@newsread1.mlpsca01.us.to.ve rio.net> Victor
> Bazarov wrote:
>[color=green]
>>Alexander Stippler wrote:
>>[color=darkred]
>>>What I originally wanted was some SFINAE construct for a constructor.
>>>Is this somehow possible without operating with a return value? I
>>>have the following: template <typename T> class A {
>>> public:
>>> template <typename S>
>>> A(const B<S> &rhs);
>>>};
>>>
>>>I have several instantiations of S and would like to allow all but
>>>one. That's the reason for this
>>>::Type construction which would then not be defined for this special
>>>::type. Is there a way to realize
>>>this concept?[/color]
>>
>>Let me get this straight... You're trying to allow construction from
>>all B<S> except some specific B<SS>, right? SFINAE is a "selection"
>>mechanism that allows to "fall back" onto some generic solution
>>instead of another particular one. Is that what you want? What would
>>be that generic solution?[/color]
>
>[color=green]
>>Or do you, in fact, need to prohibit
>>conversion of that B<SS> into A<T>, for all T, but for a particular SS?
>>And you need this in compile-time, correct?
>>[/color]
>
>
> Sorry for being unprecise. That's it, your second guess is absolutely
> what I want. The compiler shall not consider the constructor above for
> one specific SS. But how to realize?[/color]

Ok, let me restate the problem:
-------------------------------------------------
template<class T> class From {};
class Special {};
// template<> class From<Special> {}; // you don't need this, actually

template<class T> class To {
public:
template<class U> To(const From<U>&);
};

int main() {
From<int> good;
From<Special> bad;
To<int> to_int(good);
To<char> to_char(good);
To<int> to_int2(bad); // ******************** should not compile!
}
-------------------------------------------------
As is, without any special trick, the code above compiles (or at least
should compile with a compliant compiler), nothing to it.

Now, if we need to prohibit construction of 'To' from a particular From
instantiation we could define a non-template constructor (overloaded
constructor) from that type in the _private_ section of the 'To' template:
-------------
....
template<class T> class To {
To(const From<Special>&);
public:
template<class U> To(const From<U>&);
};
....
-------------
Having the overloaded constructor in the private section does not let
the 'to_int2' to be instantiated from 'bad', but only _outside_ of the
class template 'To' itself.

Is this something you can use or do you need a more generic solution?

Victor
Alexander Stippler
Guest
 
Posts: n/a
#13: Oct 26 '05

re: conversion constructor


In <psQ7f.43389$Tf5.23471@newsread1.mlpsca01.us.to.ve rio.net> Victor
Bazarov wrote:[color=blue]
> Alexander Stippler wrote:[color=green]
>> In <v6Q7f.43343$Tf5.16429@newsread1.mlpsca01.us.to.ve rio.net> Victor
>> Bazarov wrote:
>>[color=darkred]
>>>Alexander Stippler wrote:
>>>
>>>>What I originally wanted was some SFINAE construct for a constructor.
>>>>Is this somehow possible without operating with a return value? I
>>>>have the following: template <typename T> class A {
>>>> public:
>>>> template <typename S>
>>>> A(const B<S> &rhs);
>>>>};
>>>>
>>>>I have several instantiations of S and would like to allow all but
>>>>one. That's the reason for this
>>>>::Type construction which would then not be defined for this special
>>>>::type. Is there a way to realize
>>>>this concept?
>>>
>>>Let me get this straight... You're trying to allow construction from
>>>all B<S> except some specific B<SS>, right? SFINAE is a "selection"
>>>mechanism that allows to "fall back" onto some generic solution
>>>instead of another particular one. Is that what you want? What
>>>would be that generic solution?[/color]
>>
>>[color=darkred]
>>>Or do you, in fact, need to prohibit
>>>conversion of that B<SS> into A<T>, for all T, but for a particular
>>>SS? And you need this in compile-time, correct?[/color]
>>
>>
>> Sorry for being unprecise. That's it, your second guess is absolutely
>> what I want. The compiler shall not consider the constructor above
>> for one specific SS. But how to realize?[/color]
>
> Ok, let me restate the problem:
> -------------------------------------------------
> template<class T> class From {};
> class Special {};
> // template<> class From<Special> {}; // you don't need this, actually
>
> template<class T> class To {
> public:
> template<class U> To(const From<U>&);
>};
>
> int main() {
> From<int> good;
> From<Special> bad;
> To<int> to_int(good);
> To<char> to_char(good);
> To<int> to_int2(bad); // ******************** should not compile!
>}
> -------------------------------------------------
> As is, without any special trick, the code above compiles (or at least
> should compile with a compliant compiler), nothing to it.
>
> Now, if we need to prohibit construction of 'To' from a particular
> From instantiation we could define a non-template constructor (
> overloaded constructor) from that type in the _private_ section of the
> 'To' template: ------------- .... template<class T> class To { To(
> const From<Special>&); public: template<class U> To(const From<U>&);
>};
> ....
> -------------
> Having the overloaded constructor in the private section does not let
> the 'to_int2' to be instantiated from 'bad', but only _outside_ of the
> class template 'To' itself.
>
> Is this something you can use or do you need a more generic solution?
>
> Victor
>[/color]

Thanks for your effort. Trying to figure out if your solution works for
me, I realized I probably haven't completely understood my problem.
(Nevertheless your answers gave me new inspiration in another field :-))
So I post my original problem to you again hoping you can comprehend the
compiler behavior:

template <typename Impl>
class Vector
{
};

template <typename Ref>
class VectorView
: : public Vector<VectorView<Ref> >
{
public:
operator const Ref &() const {}
};

template <typename T>
class DenseVector
: : public Vector<DenseVector<T> >
{
public:
DenseVector() {}

template <typename Impl>
DenseVector(const Vector<Impl> &rhs) {}

VectorView<DenseVector<T> >
operator()(int from, int to) {}
};

int amin(const DenseVector<double> &x) { return 1; }
int amin(const DenseVector<float> &x) { return -1; }

int
main()
{
DenseVector<double> x;
int i = amin(x(1,3));
}

The way I would want it to work is that if a VectorView<DenseVector<T> >
object is used in a function where the signature expects a
DenseVector<T>
then it should be used converted to DenseVector<T>, but not allowed to
be
converted to DenseVector<OTHER_T>.
Please ask, if anything is not clear. The code above results in:

small.cc:36: error: call of overloaded 'amin(
VectorView<DenseVector<double> >)' is ambiguous
small.cc:29: note: candidates are: int amin(const DenseVector<double>&)
small.cc:30: note: int amin(const DenseVector<float>&)
Victor Bazarov
Guest
 
Posts: n/a
#14: Oct 26 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> [..] Trying to figure out if your solution works for
> me, I realized I probably haven't completely understood my problem.
> (Nevertheless your answers gave me new inspiration in another field :-))
> So I post my original problem to you again hoping you can comprehend the
> compiler behavior:
>
> template <typename Impl>
> class Vector
> {
> };
>
> template <typename Ref>
> class VectorView
> : : public Vector<VectorView<Ref> >
> {
> public:
> operator const Ref &() const {}
> };
>
> template <typename T>
> class DenseVector
> : : public Vector<DenseVector<T> >
> {
> public:
> DenseVector() {}
>
> template <typename Impl>
> DenseVector(const Vector<Impl> &rhs) {}[/color]

Why is this a template, then? Shouldn't it just be a straight-up
parameterized constructor? See my example below.
[color=blue]
> VectorView<DenseVector<T> >
> operator()(int from, int to) {}
> };
>
> int amin(const DenseVector<double> &x) { return 1; }
> int amin(const DenseVector<float> &x) { return -1; }
>
> int
> main()
> {
> DenseVector<double> x;
> int i = amin(x(1,3));
> }
>
> The way I would want it to work is that if a VectorView<DenseVector<T> >
> object is used in a function where the signature expects a
> DenseVector<T>
> then it should be used converted to DenseVector<T>, but not allowed to
> be
> converted to DenseVector<OTHER_T>.
> Please ask, if anything is not clear. The code above results in:
>
> small.cc:36: error: call of overloaded 'amin(
> VectorView<DenseVector<double> >)' is ambiguous
> small.cc:29: note: candidates are: int amin(const DenseVector<double>&)
> small.cc:30: note: int amin(const DenseVector<float>&)[/color]

template<class Impl>
class Vector
{
};

template<class Ref>
class VectorView: public Vector<VectorView<Ref> >
{
Ref r;
public:
VectorView() : Vector<VectorView<Ref> >() {}
operator const Ref &() const { return r; }
};

template<class T>
class DenseVector: public Vector<DenseVector<T> >
{
public:
DenseVector() {}
DenseVector(const Vector<T> &rhs) {}

VectorView<DenseVector<T> > operator()(int from, int to)
{
return VectorView<DenseVector<T> >();
}
};

int amin(const DenseVector<double> &x) { return 1; }
int amin(const DenseVector<float> &x) { return -1; }

int main()
{
DenseVector<double> x;
return amin(x(1,3));
}
-----------------------------------------

V
Greg
Guest
 
Posts: n/a
#15: Oct 27 '05

re: conversion constructor


Alexander Stippler wrote:[color=blue]
> In <TeP7f.43299$Tf5.7990@newsread1.mlpsca01.us.to.ver io.net> Victor
> Bazarov wrote:[color=green]
> > Alexander Stippler wrote:[color=darkred]
> >> [..]
> >> with explicit call I meant
> >> One<int> y(Two<int>());
> >> instead of
> >> One<int> y = Two<int>();
> >> with regard to the keyword 'explicit'.
> >> And I still do not understand why the first works, whereas the second
> >> doesn't.[/color]
> >
> > Try accessing any members of "y" now :-)[/color]
>
> Oh yes, I fell into this trap quite often :-((. So the solution I wanted
> is not realizable.
> What I originally wanted was some SFINAE construct for a constructor. Is
> this somehow possible
> without operating with a return value? I have the following:
>
> template <typename T>
> class A
> {
> public:
> template <typename S>
> A(const B<S> &rhs);
> };
>
> I have several instantiations of S and would like to allow all but one.
> That's the reason for this
> ::Type construction which would then not be defined for this special type. Is there a way to realize
> this concept?[/color]

Why not declare (but not define) a private constructor for the
disallowed type (SS in the following example):

class SS;

template <class T>
class A
{
public:
template <class S>
A( const B<S>& rhs);

private:
A (const B<SS>& rhs);
};

Since the compiler prefers non-template functions over template
functions when resolving an overload, the private constructor will be
the one selected when trying to convert a B<SS> to a class A object.

Greg

Alexander Stippler
Guest
 
Posts: n/a
#16: Oct 27 '05

re: conversion constructor


In <_pS7f.43592$Tf5.3771@newsread1.mlpsca01.us.to.ver io.net> Victor
Bazarov wrote:[color=blue]
> Alexander Stippler wrote:[color=green]
>> [..] Trying to figure out if your solution works for
>> me, I realized I probably haven't completely understood my problem.
>> (Nevertheless your answers gave me new inspiration in another field :-))
>> So I post my original problem to you again hoping you can comprehend
>> the compiler behavior: template <typename Impl> class Vector {
>> };
>>
>> template <typename Ref>
>> class VectorView
>> : : public Vector<VectorView<Ref> >
>> {
>> public:
>> operator const Ref &() const {}
>> };
>>
>> template <typename T>
>> class DenseVector
>> : : public Vector<DenseVector<T> >
>> {
>> public:
>> DenseVector() {}
>>
>> template <typename Impl>
>> DenseVector(const Vector<Impl> &rhs) {}[/color]
>
> Why is this a template, then? Shouldn't it just be a straight-up
> parameterized constructor? See my example below.
>[/color]

because Impl is never T. It may be DenseVector<T>, but here the copy
constructor will be chosen. Impl can be instantiated by various types
of Vectors, e.g. VectorClosure<Op, Lhs, Rhs>, also derived from Vector.
For all other types of Impl the behavior is OK. But for VectorView
(representing some sub-vector) the VectorView object shall only be
converted back to the underlying vector type, but the compiler
considers the template constructor and thus finds ambiguities. Short:
All other vector types convertible by the template constructor.
VectorView<Ref> only convertibe to Ref. That's what I want. The code
was only the shortest way to present the problem. I have several Matrix
as well as Vector types.
[color=blue][color=green]
>> VectorView<DenseVector<T> >
>> operator()(int from, int to) {}
>> };
>>
>> int amin(const DenseVector<double> &x) { return 1; }
>> int amin(const DenseVector<float> &x) { return -1; }
>>
>> int
>> main()
>> {
>> DenseVector<double> x;
>> int i = amin(x(1,3));
>> }
>>
>> The way I would want it to work is that if a
>> VectorView<DenseVector<T> > object is used in a function where the
>> signature expects a DenseVector<T> then it should be used converted
>> to DenseVector<T>, but not allowed to be converted to
>> DenseVector<OTHER_T>. Please ask, if anything is not clear. The code
>> above results in: small.cc:36: error: call of overloaded 'amin(
>> VectorView<DenseVector<double> >)' is ambiguous small.cc:29: note:
>> candidates are: int amin(const DenseVector<double>&) small.cc:30:
>> note: int amin(const DenseVector<float>&)[/color]
>
> template<class Impl>
> class Vector
> {
>};
>
> template<class Ref>
> class VectorView: public Vector<VectorView<Ref> >
> {
> Ref r;
> public:
> VectorView() : Vector<VectorView<Ref> >() {}
> operator const Ref &() const { return r; }
>};
>
> template<class T>
> class DenseVector: public Vector<DenseVector<T> >
> {
> public:
> DenseVector() {}
> DenseVector(const Vector<T> &rhs) {}
>
> VectorView<DenseVector<T> > operator()(int from, int to)
> {
> return VectorView<DenseVector<T> >();
>} } ;
>
> int amin(const DenseVector<double> &x) { return 1; }
> int amin(const DenseVector<float> &x) { return -1; }
>
> int main()
> {
> DenseVector<double> x;
> return amin(x(1,3));
>}
> -----------------------------------------
>
> V
>[/color]
Closed Thread