Dear advanced c/g++ programers: I tried to test a piece code about Defining constrained Value Types -------------------------------------------------------------------------------------------------------- // Example 5-10 constrained_value.hpp #ifndef CINSTRAINED_VALUE_HPP #define CONSTRAINED_VALUE_HPP #include <cstdlib> #include <iostream> using namespace std; template<class Policy_T> struct ConstrainedValue { public: // public typedefs typedef typename Policy_T policy_type; typedef typename Policy_T::value_type value_type; typedef ConstrainedValue self; // default constructor ConstrainedValue() : m(Policy_T::default_value) { } ConstrainedValue(const self& x) : m(x.m) { } ConstrainedValue(const value_type& x) { Policy_T::assign(m, x); } operator value_type() const { return m; } // uses the policy defined assign function void assign(const value_type& x) { Policy_T::assign(m, x); } // assignment operations self& operator=(const value_type& x) { assign(x); return *this; } self& operator+=(const value_type& x) { assign(m + x); return *this; } self& operator-=(const value_type& x) { assign(m - x); return *this; } self& operator*=(const value_type& x) { assign(m * x); return *this; } self& operator/=(const value_type& x) { assign(m / x); return *this; } self& operator%=(const value_type& x) { assign(m % x); return *this; } self& operator>>=(int x) { assign(m >> x); return *this; } self& operator<<=(int x) { assign(m << x); return *this; } // unary operations self operator-() { return self(-m); } self operator+() { return self(+m); } self operator!() { return self(!m); } self operator~() { return self(~m); } // binary operations friend self operator+(self x, const value_type& y) { return x += y; } friend self operator-(self x, const value_type& y) { return x -= y; } friend self operator*(self x, const value_type& y) { return x *= y; } friend self operator/(self x, const value_type& y) { return x /= y; } friend self operator%(self x, const value_type& y) { return x %= y; } friend self operator+(const value_type& y, self x) { return x += y; } friend self operator-(const value_type& y, self x) { return x -= y; } friend self operator*(const value_type& y, self x) { return x *= y; } friend self operator/(const value_type& y, self x) { return x /= y; } friend self operator%(const value_tyep& y, self x) { return x %= y; } friend self operator>>(self x, int y) { return x >>= y; } friend self operator<<(self x, int y) { return x <<= y; } // stream operators friend ostream& operator<<(ostream& o, self x) { o << x.m; return o; } friend istream& operator>>(istream& i, self x) { value_type tmp; i >> tmp; x.assign(tmp); return i; } // comparison operators friend bool operator<(const self& x, const self& y) { return x.m < y.m; } friend bool operator>(const self& x, const self& y) { return x.m > y.m; } friend bool operator<=(const self& x, const self& y) { return x.m <= y.m; } friend bool operator>=(const self& x, const self& y) { return x.m >= y.m; } friend bool operator==(const self& x, const self& y) { return x.m == y.m; } friend bool operator!=(const self& x, const self& y) { return x.m != y.m; } private: value_type m; }; template<int Min_N, int Max_N> struct RangedIntPolicy { typedef int value_type; const static value_type default_value = Min_N; static void assign(value_type& lvalue, const value_type& rvalue) { if ((rvalue < <Min_N) || (rvalue > Max_N)) { throw range_error("out of valie range"); } lvalue = rvalue; } }; #endif ---------------------------------------------------------------------------------------------------------------------------------- // Example 5-11. Using constrained_value.hpp #include "constrained_value.hpp" typedef ConstrainedValue< RangedIntPolicy<1582, 4000> > GregYear; typedef ConstrainedValue< RangedIntPolicy<1, 12> > GregMonth; typedef ConstrainedValue< RangedIntPolicy<1, 31> > GregDayOfMonth; using namespace std; void gregOutputDate(GregDayOfMonth d, GregMonth m, GregYear y) { cout << m << "/" << d << "/" << y << endl; } int main() { try { gregOutputDate(14, 7, 2005); } catch(...) { cerr << "whoops, shouldn't be here" << endl; } try { gregOutputDate(1, 5, 1148); cerr << "whoops, shouldn't be here" << endl; } catch(...) { cerr << "are are sure you want to be using a Gregorian Calendar?" << endl; } } ------------------------------------------------------------------------------------------------------------------------- eric@eric-laptop:~/cppcookbook/download$ g++ 5-11.cpp In file included from 5-11.cpp:1:0: constrained_value.hpp:14:22: error: expected nested-name-specifier before ‘Policy_T’ constrained_value.hpp:14:31: error: expected ‘;’ before ‘policy_type’ constrained_value.hpp: In static member function ‘static void RangedIntPolicy<Min_N, Max_N>::assign(RangedIntPolicy::value_type&, const RangedIntPolicy::value_type&)’: constrained_value.hpp:83:45: error: there are no arguments to ‘range_error’ that depend on a template parameter, so a declaration of ‘range_error’ must be available constrained_value.hpp:83:45: note: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated) constrained_value.hpp: In static member function ‘static void RangedIntPolicy<Min_N, Max_N>::assign(RangedIntPolicy::value_type&, const RangedIntPolicy::value_type&) [with int Min_N = 1, int Max_N = 31, RangedIntPolicy::value_type = int]’: constrained_value.hpp:21:45: instantiated from ‘ConstrainedValue<Policy_T>::ConstrainedValue(ConstrainedValue<Policy_T>::value_type&) [with Policy_T = RangedIntPolicy<1, 31>, ConstrainedValue<Policy_T>::value_type = int]’ 5-11.cpp:15:31: instantiated from here constrained_value.hpp:83:7: error: ‘range_error’ was not declared in this scope constrained_value.hpp: In static member function ‘static void RangedIntPolicy<Min_N, Max_N>::assign(RangedIntPolicy::value_type&, const RangedIntPolicy::value_type&) [with int Min_N = 1, int Max_N = 12, RangedIntPolicy::value_type = int]’: constrained_value.hpp:21:45: instantiated from ‘ConstrainedValue<Policy_T>::ConstrainedValue(ConstrainedValue<Policy_T>::value_type&) [with Policy_T = RangedIntPolicy<1, 12>, ConstrainedValue<Policy_T>::value_type = int]’ 5-11.cpp:15:31: instantiated from here constrained_value.hpp:83:7: error: ‘range_error’ was not declared in this scope constrained_value.hpp: In static member function ‘static void RangedIntPolicy<Min_N, Max_N>::assign(RangedIntPolicy::value_type&, const RangedIntPolicy::value_type&) [with int Min_N = 1582, int Max_N = 4000, RangedIntPolicy::value_type = int]’: constrained_value.hpp:21:45: instantiated from ‘ConstrainedValue<Policy_T>::ConstrainedValue(ConstrainedValue<Policy_T>::value_type&) [with Policy_T = RangedIntPolicy<1582, 4000>, ConstrainedValue<Policy_T>::value_type = int]’ 5-11.cpp:15:31: instantiated from here constrained_value.hpp:83:7: error: ‘range_error’ was not declared in this scope eric@eric-laptop:~/cppcookbook/download$ ---------------------------------------------------------------------------------------------------------------------------------------- if you worry about I have typo, feel free to download and test by yourself at http://examples.oreilly.com/9780596007614/ Do you know what may cause compile error expected nested-name-specifier before 'Policy-T'? thanks your help a lot in advance Eric