Re: Expression templates --- code not compiling
On 2011-07-11 00:24, Carlos Moreno wrote:
Hi,
I'm trying the sample code from Wikipedia's page on
Expression templates --- just for testing purposes
(I want to make sure that I, an my compiler, get this
right before attempting what I need to do).
The link to the version as I'm using it is:
http://en.wikipedia.org/w/index.php?title=Expression_templates&oldid=438479980
[..]
The code does not compile with gcc/g++ 4.5.2 (the
version that comes with Ubuntu 11.04). The error
seems puzzling: it does not recognize the method
size(). Here's the exact output:
expression_templates.c++: In constructor ?VecDifference<E1,
E2>::VecDifference(const VecExpression<E>&, const VecExpression<E2>&)
[with E1 = Vec, E2 = Vec]?:
expression_templates.c++:91:35: instantiated from ?const
VecDifference<E1, E2> operator-(const VecExpression<E>&, const
VecExpression<E2>&) [with E1 = Vec, E2 = Vec]?
expression_templates.c++:103:21: instantiated from here
expression_templates.c++:66:5: error: no matching function for call to
?VecExpression<Vec>::size() const?
expression_templates.c++:66:5: error: no matching function for call to
?VecExpression<Vec>::size() const?
The Wikipedia example is indeed broken, but are you sure that you quoted
the complete compiler message? I see two defects in the code:
a) Within the declarations of CRTP base class VecExpression you cannot
refer to typedefs of the derived type E directly. This is so, because at
the point, where E derives from VecExpression<E>, VecExpression<E> needs
to be a complete type, but it is not, because it refers to the yet
incomplete type E.
b) I don't see any reason for the usage of the 'template' prefix within
the VecDifference constructor assertion:
assert(u.template size<E1>() == v.template size<E2>());
The sample in Wikipedia's page does not include
client code, so I put what I thought would be an
obvious example (hopefully the fragment below is
ok?):
int main()
{
Vec a(100000), b(100000);
Vec c (2.5*(a - b));
cout << c[0] << endl;
return 0;
}
This example is broken as well. You need to include <iostream> and you
need to refer to namespace std.
Line 103 is the instantiation of c
Line 91 is the return statement in the definition
of operator-
Line 66 is the assert (using .size() inside the
constructor for VecDifference)
How can it not find XXX::size(), when it is defined
in each and every one of the classes in the code?
If I replace every instance of size() with a hardcoded
constant (a global const int N = 100000 and replace
every call to xxx.size() with N, then it compiles,
and it runs without segfaults --- it prints 120, though,
which does not seem right).
What am I missing?
The usage of size within the function bodies of the CRTB base class is
OK, but the function declarations cannot refer to members of the derived
class directly. You need to apply indirection techniques (e.g. a traits
class) to transfer this information down.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]