"could not deduce template argument" error

G

gretean

I have a problem that's driving me crazy involving Microsoft's ability
to deduce template parameters. I am using Visual Studio .NET (aka
VC7?), and it gives an error compiling the following code.

template <int x, int y> class M {
public:
template <int xRet, int yRet, int xR, int yR>
M<xRet, yRet> operator *(const M<xR, yR> &b) const {
M<xRet,yRet> a;
return a;
}
};

int main() {
M<1,2> a;
M<3,4> b;
M<5,6> c;
c = a * b;
return 0;
}

The error I get is

error C2783: 'M<xRet,yRet> M<x,y>::eek:perator *(const M<xR,yR> &) const'
: could not deduce template argument for 'xRet'
with
[
x=1,
y=2
]

Can somebody please explain to me what is syntactically wrong with
this? I'm not looking for advice or lectures about why ints shouldn't
be used in template parameters, so please don't respond with such. I'm
just wondering what part of this C++ syntax is invalid. To me it seems
like it should be fine. Thanks.
 
N

Nindi73

if u look at your code .. forget about 'c=a*b' just look at 'a*b' ..
you know what x is, what y is, what xR is and what yR is ... but how is
the compiler supposedd to work out what xRet and yRet is ?

when 'a*b' takes place .. c is not in the picture .. so it can't work
it from c


I hope that helps
 
A

Andrey Tarasevich

...
template <int x, int y> class M {
public:
template <int xRet, int yRet, int xR, int yR>
M<xRet, yRet> operator *(const M<xR, yR> &b) const {
M<xRet,yRet> a;
return a;
}
};

int main() {
M<1,2> a;
M<3,4> b;
M<5,6> c;
c = a * b;
return 0;
}

The error I get is

error C2783: 'M<xRet,yRet> M<x,y>::eek:perator *(const M<xR,yR> &) const'
: could not deduce template argument for 'xRet'
with
[
x=1,
y=2
]

Can somebody please explain to me what is syntactically wrong with
this?

Argument deduction for function templates is always based on the types of actual
function arguments and _only_ on these types.

In this case the arguments are 'a' and 'b'. The type of 'b' allows compiler to
deduce 'xR' and 'yR' arguments. But there's absolutely no way the compiler can
deduce 'xRet' and 'yRet' from types of 'a' and/or 'b'. That's what the compiler
is trying to tell you.

It appears that you expect the compiler to take 'c' into account. That not how
it works in C++. Template argument deduction does not take into account the
"expected" return type of the function. It works with function arguments only.
 
G

gretean

Andrey said:
...
template <int x, int y> class M {
public:
template <int xRet, int yRet, int xR, int yR>
M<xRet, yRet> operator *(const M<xR, yR> &b) const {
M<xRet,yRet> a;
return a;
}
};

int main() {
M<1,2> a;
M<3,4> b;
M<5,6> c;
c = a * b;
return 0;
}

The error I get is

error C2783: 'M<xRet,yRet> M<x,y>::eek:perator *(const M<xR,yR> &) const'
: could not deduce template argument for 'xRet'
with
[
x=1,
y=2
]

Can somebody please explain to me what is syntactically wrong with
this?

Argument deduction for function templates is always based on the types of actual
function arguments and _only_ on these types.

In this case the arguments are 'a' and 'b'. The type of 'b' allows compiler to
deduce 'xR' and 'yR' arguments. But there's absolutely no way the compiler can
deduce 'xRet' and 'yRet' from types of 'a' and/or 'b'. That's what the compiler
is trying to tell you.

It appears that you expect the compiler to take 'c' into account. That not how
it works in C++. Template argument deduction does not take into account the
"expected" return type of the function. It works with function arguments only.

Thanks.

I'm wondering though -- do you think I can make the compiler take "c
into account" by overloading an assignment operator? It sounds like
that might be possible, since c is an argument to operator = in this
case.
 
N

Nindi73

I don't think that will work ... its to late ....a*b doesn't get to
see c at all


Andrey said:
...
template <int x, int y> class M {
public:
template <int xRet, int yRet, int xR, int yR>
M<xRet, yRet> operator *(const M<xR, yR> &b) const {
M<xRet,yRet> a;
return a;
}
};

int main() {
M<1,2> a;
M<3,4> b;
M<5,6> c;
c = a * b;
return 0;
}

The error I get is

error C2783: 'M<xRet,yRet> M<x,y>::eek:perator *(const M<xR,yR> &) const'
: could not deduce template argument for 'xRet'
with
[
x=1,
y=2
]

Can somebody please explain to me what is syntactically wrong with
this?

Argument deduction for function templates is always based on the types of actual
function arguments and _only_ on these types.

In this case the arguments are 'a' and 'b'. The type of 'b' allows compiler to
deduce 'xR' and 'yR' arguments. But there's absolutely no way the compiler can
deduce 'xRet' and 'yRet' from types of 'a' and/or 'b'. That's what the compiler
is trying to tell you.

It appears that you expect the compiler to take 'c' into account. That not how
it works in C++. Template argument deduction does not take into account the
"expected" return type of the function. It works with function arguments only.

Thanks.

I'm wondering though -- do you think I can make the compiler take "c
into account" by overloading an assignment operator? It sounds like
that might be possible, since c is an argument to operator = in this
case.
 
N

Nindi73

The other thing you should take into account is that all the template
parametres, the ints are compile time known constants, the
multiplication, how ever its defined maybe be computed at compile time.

template<int i, int j>
struct A {

enum {first = i, second =j};
};

template<class A1,class A2>
struct Mult;

template<int i1,int j1, int i2, int j2>
struct Mult< A<i1,j1> , A<i2,j2> > {
typedef A<i1 * i2 , j1* j2 > type;
};


then to compute the result of Multiplication I do this

Mult<A<1,2>, A <2,3> >::type res;

res is now the correct M<i,j>

or maybe something like this.





I don't think that will work ... its to late ....a*b doesn't get to
see c at all


Andrey said:
(e-mail address removed) wrote:
...
template <int x, int y> class M {
public:
template <int xRet, int yRet, int xR, int yR>
M<xRet, yRet> operator *(const M<xR, yR> &b) const {
M<xRet,yRet> a;
return a;
}
};

int main() {
M<1,2> a;
M<3,4> b;
M<5,6> c;
c = a * b;
return 0;
}

The error I get is

error C2783: 'M<xRet,yRet> M<x,y>::eek:perator *(const M<xR,yR> &) const'
: could not deduce template argument for 'xRet'
with
[
x=1,
y=2
]

Can somebody please explain to me what is syntactically wrong with
this?

Argument deduction for function templates is always based on the types of actual
function arguments and _only_ on these types.

In this case the arguments are 'a' and 'b'. The type of 'b' allows compiler to
deduce 'xR' and 'yR' arguments. But there's absolutely no way the compiler can
deduce 'xRet' and 'yRet' from types of 'a' and/or 'b'. That's what the compiler
is trying to tell you.

It appears that you expect the compiler to take 'c' into account. That not how
it works in C++. Template argument deduction does not take into account the
"expected" return type of the function. It works with function arguments only.

Thanks.

I'm wondering though -- do you think I can make the compiler take "c
into account" by overloading an assignment operator? It sounds like
that might be possible, since c is an argument to operator = in this
case.
 
N

Nindi73

What EXACTLY are you trying to do ?

The other thing you should take into account is that all the template
parametres, the ints are compile time known constants, the
multiplication, how ever its defined maybe be computed at compile time.

template<int i, int j>
struct A {

enum {first = i, second =j};
};

template<class A1,class A2>
struct Mult;

template<int i1,int j1, int i2, int j2>
struct Mult< A<i1,j1> , A<i2,j2> > {
typedef A<i1 * i2 , j1* j2 > type;
};


then to compute the result of Multiplication I do this

Mult<A<1,2>, A <2,3> >::type res;

res is now the correct M<i,j>

or maybe something like this.





I don't think that will work ... its to late ....a*b doesn't get to
see c at all


Andrey Tarasevich wrote:
(e-mail address removed) wrote:
...
template <int x, int y> class M {
public:
template <int xRet, int yRet, int xR, int yR>
M<xRet, yRet> operator *(const M<xR, yR> &b) const {
M<xRet,yRet> a;
return a;
}
};

int main() {
M<1,2> a;
M<3,4> b;
M<5,6> c;
c = a * b;
return 0;
}

The error I get is

error C2783: 'M<xRet,yRet> M<x,y>::eek:perator *(const M<xR,yR> &) const'
: could not deduce template argument for 'xRet'
with
[
x=1,
y=2
]

Can somebody please explain to me what is syntactically wrong with
this?

Argument deduction for function templates is always based on the types of actual
function arguments and _only_ on these types.

In this case the arguments are 'a' and 'b'. The type of 'b' allows compiler to
deduce 'xR' and 'yR' arguments. But there's absolutely no way the compiler can
deduce 'xRet' and 'yRet' from types of 'a' and/or 'b'. That's what the compiler
is trying to tell you.

It appears that you expect the compiler to take 'c' into account. That not how
it works in C++. Template argument deduction does not take into account the
"expected" return type of the function. It works with function arguments only.

Thanks.

I'm wondering though -- do you think I can make the compiler take "c
into account" by overloading an assignment operator? It sounds like
that might be possible, since c is an argument to operator = in this
case.
 
G

gretean

What EXACTLY are you trying to do ?

I want to define a matrix type that can be sized dynamically (e.g., by
SetNumRows and SetNumCols member functions) but is limited to a maximum
size by the template parameters.

You may be wondering why, so the reasons are as follows:
1. The matrix cannot use new and delete in its implementation.
2. The dynamic sizing allows us to save memory.

By defining the appropriate assignment operator, I got it to work.

Thanks for the responses.
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top