bug with tricky template example in gcc 3.0.2
Nicolai Josuttis
solutions@josuttis.de
Sat Feb 2 08:03:00 GMT 2002
Hi,
for our upcoming C++ templates book we wrote the tricky program
to have named template arguments.
As far as we know, this program is correct.
However, gcc 3.0.2 prints a syntax error.
Could you have a look at it, please
adn give us feedback so that we might add a footnoe inside the
book, if necessary?
Thanks and best
Nico
gcc -v:
Reading specs from /local/gcc/rundir/lib/gcc-lib/i686-pc-linux-gnu/3.0.2/specs
Configured with: /local/gcc/srcdir/configure --prefix /local/gcc/rundir
--enable-languages=c++
Thread model: single
gcc version 3.0.2
program:
attached as namedtmpl.cpp
call and output:
/local/gcc/rundir/bin/g++ -g -ansi -W -Wall -Wwrite-strings -Wstrict-prototypes
-Wmissing-prototypes -Wtraditional -pedantic -c namedtmpl.cpp
namedtmpl.cpp: In member function `void BreadSlicer<PolicySetter1,
PolicySetter2, PolicySetter3, PolicySetter4>::print()':
namedtmpl.cpp:88: parse error before `;' token
make: *** [namedtmpl.o] Error 1
--
Nicolai M. Josuttis http://www.josuttis.de/
Solutions in Time mailto:solutions@josuttis.de
-------------- next part --------------
#include <iostream>
// {PolicySelector<A,B,C,D> creates {A,B,C,D} as base classes}
// - {Discriminator<> allows having even the same base class more than once}
template <typename Base, int D>
class Discriminator : public Base {
};
template <typename Setter1, typename Setter2,
typename Setter3, typename Setter4>
class PolicySelector : public Discriminator<Setter1,1>,
public Discriminator<Setter2,2>,
public Discriminator<Setter3,3>,
public Discriminator<Setter4,4> {
};
// default policies
class DefaultPolicy1 {};
class DefaultPolicy2 {};
class DefaultPolicy3 {
public:
static void doPrint() {
std::cout << "DefaultPolicy3::doPrint()\n";
}
};
class DefaultPolicy4 {};
// define default policies as {P1, P2, P3, P4}
class DefaultPolicies {
public:
typedef DefaultPolicy1 P1;
typedef DefaultPolicy2 P2;
typedef DefaultPolicy3 P3;
typedef DefaultPolicy4 P4;
};
// class to define a usage of the default policy values
// - avoids ambiguities if we derive from {\tt DefaultPolicies more than once}
class DefaultPolicyArgs : virtual public DefaultPolicies {
};
// class templates to override the default policy values
template <typename Policy>
class Policy1_is : virtual public DefaultPolicies {
public:
typedef Policy P1; // overriding typedef
};
template <typename Policy>
class Policy2_is : virtual public DefaultPolicies {
public:
typedef Policy P2; // overriding typedef
};
template <typename Policy>
class Policy3_is : virtual public DefaultPolicies {
public:
typedef Policy P3; // overriding typedef
};
template <typename Policy>
class Policy4_is : virtual public DefaultPolicies {
public:
typedef Policy P4; // overriding typedef
};
// create class template with four policies and default values
template <typename PolicySetter1 = DefaultPolicyArgs,
typename PolicySetter2 = DefaultPolicyArgs,
typename PolicySetter3 = DefaultPolicyArgs,
typename PolicySetter4 = DefaultPolicyArgs>
class BreadSlicer {
typedef PolicySelector<PolicySetter1, PolicySetter2,
PolicySetter3, PolicySetter4>
Policies;
// use \T{Policies::P1, \T{Policies::P2}, ... to refer to the various policies.}
public:
void print () {
Policies::P3::doPrint();
}
//...
};
// define a custom policy
class CustomPolicy {
public:
static void doPrint() {
std::cout << "CustomPolicy::doPrint()\n";
}
};
int main()
{
BreadSlicer<> bc1;
bc1.print();
BreadSlicer<Policy3_is<CustomPolicy> > bc2;
bc2.print();
}
More information about the Gcc-bugs
mailing list