Topic: Template instantiation - nonsensical member functions
Author: bglenden@colobus.cv.nrao.edu (Brian Glendenning)
Date: Mon, 29 Mar 1993 13:39:29 GMT Raw View
My understanding of the template instantiation "philosophy" of C++
(e.g. an article in the latest "C++ Report") is that member functions
are only instantiated if they are used. For example, given a templated
vector type:
Vector<int> vi(10);
Vector<String> vs(10);
vi(3) = 3;
vs(3) = "three";
vi -= 1; // Decrement each element of vi by 1
is all OK, but
vs -= "Foo";
Would cause a problem (presuming that -= isn't defined for Strings).
However in my CFront 3.0 based implementation (Sun version 2.0.1) it
doesn't seem to behave this way, i.e. even though I don't use -=
anywhere, I get an error like:
"./vector.C", line 22: error: bad operands for -=: String -= const String
"./vector.C", line 22: error detected during the instantiation of
Vector <String>
The only relevant flags appear to be -pts and -pta, neither one of
which appear to do the job.
So;
1. Is my understanding correct, is it the intention of the C++
standardization to "bless" having templates some of whose member
functions don't make sense for all types; and
2. How do I actually do this with current versions of CFront.
[For this toy problem a solution would be to derive a "numeric Vector"
>from a "storage Vector"; for the real problem the consequences would
be worse, among other things likely requiring MI.]
Thanks,
Brian
--
Brian Glendenning - National Radio Astronomy Observatory
bglenden@nrao.edu Charlottesville Va. (804) 296-0286
Author: bglenden@colobus.cv.nrao.edu (Brian Glendenning)
Date: Mon, 29 Mar 1993 18:34:32 GMT Raw View
In article <BGLENDEN.93Mar29083929@colobus.cv.nrao.edu> bglenden@colobus.cv.nrao.edu (Brian Glendenning) writes:
[ Question about when template member functions are instantiated; i.e.
only when used? ]
Here's a small example that I think should compile but doesn't:
#!/bin/sh
# This is a shell archive (shar 3.24)
# made 03/29/1993 18:34 UTC by bglenden@colobus
# Source directory /colobus/aips/pgmr/bglenden/tmp/vector
#
# existing files WILL be overwritten
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 76 -rw-r--r-- foo.C
# 177 -rw-r--r-- foo.h
# 414 -rw-r--r-- main.C
# 390 -rw-r--r-- vector.C
# 254 -rw-r--r-- vector.h
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
then TOUCH=touch
else TOUCH=true
fi
# ============= foo.C ==============
echo "x - extracting foo.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > foo.C &&
X#include "foo.h"
X
XFoo::Foo()
X{
X just_so_we_have_a_data_member = 0;
X}
SHAR_EOF
$TOUCH -am 0326160493 foo.C &&
chmod 0644 foo.C ||
echo "restore of foo.C failed"
set `wc -c foo.C`;Wc_c=$1
if test "$Wc_c" != "76"; then
echo original size 76, current size $Wc_c
fi
# ============= foo.h ==============
echo "x - extracting foo.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > foo.h &&
X// Just a class that cannot be used numerically
X
X#if !defined (FOO_H)
X#define FOO_H
X
Xclass Foo {
Xpublic:
X Foo();
Xprivate:
X char *just_so_we_have_a_data_member;
X};
X
X#endif
SHAR_EOF
$TOUCH -am 0326160393 foo.h &&
chmod 0644 foo.h ||
echo "restore of foo.h failed"
set `wc -c foo.h`;Wc_c=$1
if test "$Wc_c" != "177"; then
echo original size 177, current size $Wc_c
fi
# ============= main.C ==============
echo "x - extracting main.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > main.C &&
X#include "vector.h"
X#include "foo.h"
X#include <iostream.h>
X#include <assert.h>
X
Xmain()
X{
X Vector<int> vi(10);
X for (int i=0; i < 10; i++) {
X vi(i) = i;
X assert(vi(i) == i);
X }
X vi -= 1;
X for (i=0; i < 10; i++) {
X assert(vi(i) == i - 1);
X }
X
X Vector<Foo> vf(10); // Causes compilation to bar because -= is not defined
X // for Foos.
X
X
X cout << "OK\n";
X return 0;
X
X}
SHAR_EOF
$TOUCH -am 0329133393 main.C &&
chmod 0644 main.C ||
echo "restore of main.C failed"
set `wc -c main.C`;Wc_c=$1
if test "$Wc_c" != "414"; then
echo original size 414, current size $Wc_c
fi
# ============= vector.C ==============
echo "x - extracting vector.C (Text)"
sed 's/^X//' << 'SHAR_EOF' > vector.C &&
X#include "vector.h"
X
Xtemplate<class T> Vector<T>::Vector(int size)
X{
X data = new T[size];
X length = size;
X}
X
Xtemplate<class T> Vector<T>::~Vector()
X{
X delete data;
X}
X
Xtemplate<class T> T &Vector<T>::operator()(int index)
X{
X return *(data + index);
X}
X
Xtemplate<class T> void Vector<T>::operator-=(const T &val)
X{
X for (int i=0; i < length; i++) {
X *(data + i) -= val;
X }
X}
SHAR_EOF
$TOUCH -am 0326161993 vector.C &&
chmod 0644 vector.C ||
echo "restore of vector.C failed"
set `wc -c vector.C`;Wc_c=$1
if test "$Wc_c" != "390"; then
echo original size 390, current size $Wc_c
fi
# ============= vector.h ==============
echo "x - extracting vector.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > vector.h &&
X// Toy Vector class
X
X#if !defined(VECTOR_H)
X#define VECTOR_H
X
Xtemplate<class T> class Vector {
Xpublic:
X Vector(int size);
X ~Vector();
X T &operator()(int index);
X void operator-=(const T &val);
Xprivate:
X int length;
X T *data;
X};
X
X#endif
SHAR_EOF
$TOUCH -am 0326161793 vector.h &&
chmod 0644 vector.h ||
echo "restore of vector.h failed"
set `wc -c vector.h`;Wc_c=$1
if test "$Wc_c" != "254"; then
echo original size 254, current size $Wc_c
fi
exit 0
--
Brian Glendenning - National Radio Astronomy Observatory
bglenden@nrao.edu Charlottesville Va. (804) 296-0286