By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,852 Members | 2,123 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,852 IT Pros & Developers. It's quick & easy.

Template instantiation problem

P: n/a
Here is a short snippet of code that does not compile (tested with Vc8
and Comeau). This is because somehow Vector<0gets instantiated, for
which the array size goes to 0. However, I don't quite get it why it
gets instantiated in the first place. So why does not this compile?

template <int N>
struct Vector
{
int data_[N];
};

template <int HEIGHT, int WIDTH>
struct Matrix
{
};

template <int HEIGHT, int WIDTH>
Vector<WIDTHoperator *(
const Vector<HEIGHT>&,
const Matrix<HEIGHT, WIDTH>&)
{
return Vector<WIDTH>();
}

template <int HEIGHT, int WIDTH>
Vector<WIDTH - 1operator *(
const Vector<HEIGHT - 1>&,
const Matrix<HEIGHT, WIDTH>&)
{
return Vector<WIDTH - 1>();
}

int main()
{
Matrix<1, 1transform;
Vector<1translation;

translation = translation * transform;

return 0;
}

--
Kalle Rutanen
http://kaba.hilvi.org
Sep 15 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a

Kaba wrote:
Here is a short snippet of code that does not compile (tested with Vc8
and Comeau). This is because somehow Vector<0gets instantiated, for
which the array size goes to 0. However, I don't quite get it why it
gets instantiated in the first place. So why does not this compile?

template <int N>
struct Vector
{
int data_[N];
};

template <int HEIGHT, int WIDTH>
struct Matrix
{
};

template <int HEIGHT, int WIDTH>
Vector<WIDTHoperator *(
const Vector<HEIGHT>&,
const Matrix<HEIGHT, WIDTH>&)
{
return Vector<WIDTH>();
}

template <int HEIGHT, int WIDTH>
Vector<WIDTH - 1operator *(
const Vector<HEIGHT - 1>&,
const Matrix<HEIGHT, WIDTH>&)
{
return Vector<WIDTH - 1>();
}

int main()
{
Matrix<1, 1transform;
Vector<1translation;

translation = translation * transform;

return 0;
}

--
Kalle Rutanen
http://kaba.hilvi.org

what do you think the following line instantiates from your given
example ?
return Vector<WIDTH - 1>();

Sep 15 '06 #2

P: n/a
what do you think the following line instantiates from your given
example ?
return Vector<WIDTH - 1>();
Right, but a template is only instantiated when used, and I am not using
that template function (but the other). The question is: why would that
function be instantiated?

--
Kalle Rutanen
http://kaba.hilvi.org
Sep 16 '06 #3

P: n/a

Kaba wrote:
what do you think the following line instantiates from your given
example ?
return Vector<WIDTH - 1>();

Right, but a template is only instantiated when used, and I am not using
that template function (but the other). The question is: why would that
function be instantiated?
Both operator*() functions are instantiated while the compiler is
resolving which function the expression "translation * transform" is to
call.

A simple fix would be to specialize Vector<0>:

template <>
struct Vector<0>
{
};

Greg

Sep 16 '06 #4

P: n/a
Both operator*() functions are instantiated while the compiler is
resolving which function the expression "translation * transform" is to
call.
Hmm.. Yes, sounds reasonable. So the 0-array declaration here does not
go under SFINAE?
A simple fix would be to specialize Vector<0>:

template <>
struct Vector<0>
{
};
Right.

--
Kalle Rutanen
http://kaba.hilvi.org
Sep 16 '06 #5

P: n/a
Kaba wrote:
Both operator*() functions are instantiated while the compiler is
resolving which function the expression "translation * transform" is to
call.

Hmm.. Yes, sounds reasonable. So the 0-array declaration here does not
go under SFINAE?
The failure is an instantiation failure that comes before the
substitution can even be attempted. Once vector<0is instantiable
(say, by providing a specialization) then the substitution does fail
without an error.

Greg

Sep 17 '06 #6

P: n/a
Hmm.. Yes, sounds reasonable. So the 0-array declaration here does not
go under SFINAE?

The failure is an instantiation failure that comes before the
substitution can even be attempted. Once vector<0is instantiable
(say, by providing a specialization) then the substitution does fail
without an error.
I am still not convinced. Let's take another try.. I simplified the
problem:

template <int N>
struct Vector
{
int data_[N];
};

template <int N>
struct Matrix
{
};

template <int N>
int operator *(
const Vector<N>&,
const Matrix<N>&)
{
return 0;
}

template <int N>
int operator *(
const Vector<N - 1>&,
const Matrix<N>&)
{
return 1;
}

int main()
{
Matrix<1transform;
Vector<1translation;

int result = translation * transform;

return 0;
}

If I were a compiler I would act like this:

1) If in the first function I take the Matrix<1to conclude N = 1, then
the other parameter is Vector<1and we have a match.

2) If in the first function I take the Vector<1to conclude N = 1, then
the other parameter is Matrix<1and we have a match.

3) If in the second function I take the Matrix<1to conclude N = 1,
then the other parameter is Vector<0and we don't have a match.

4) If in the second function I take the Vector<1to conclude N = 2,
then the other parameter is Matrix<2and we don't have a match.

Thus, without ever needing instantiation of any template, we have
concluded that the first function is the only possible candidate. Why
would the compiler need the instantiation of Vector<0or Matrix<2>?

Btw, I reposted this question to comp.lang.c++.moderated before you
replied this second time. I thought there will be no more replies
because this newsgroup has such a traffic all the time. The comment I
make there is written before you replied, so it is not to say that you
couldn't deliver the answer.

Anyway, you still haven't convinced me of the reasons which lead to the
instantion of Vector<0>.. Examples showing its necessity and/or relevant
quotes from the standard would help.

--
Kalle Rutanen
http://kaba.hilvi.org
Sep 18 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.