E
eric
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
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