advertisement
Login | Register   
  Include Code  Search Tips
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
To facilitate the implementation of constraints, new language features are necessary. One such feature is a keyword that indicates a constraint. This keyword will instruct the compiler to evaluate the constraint for every template instance automatically. An implementation can also use this keyword to remove the constraint's code from the executable. Which other features do you think can facilitate the design and implementation of constraints? Let us know in our C++ Discussion Forum.
Partners & Affiliates
advertisement
advertisement
advertisement
advertisement
Average Rating: 3.7/5 | Rate this item | 3 users have rated this item.
Enforcing Compile-time Constraints (cont'd)
Design Improvements
Does a constraint incur runtime and space overhead? If it's checked at compile-time, you certainly don't want it to remain in the executable. Modern IDEs are clever enough to optimize away code that isn't needed in the executable. To help the compiler out, move the constraint into a separate static member function constraints() (or any other name you like). Remember to declare this member private so that other clients can't call it:

template <class T> struct POD_test
{
POD_test(){constraints();} //forces compile-time
//evaluation
private:
static void constraints()
{
union{ T t;} u;
}
};
advertisement
At Your Beck And Call
Notice that constraints() actually does nothing; it only declares a local union. Since the union isn't used, the compiler may elide the constraints() call in the constructor, thereby avoiding its overhead.

"must be POD" is only one example of the numerous constraints you can enforce. Another common constraint is "must be T." Implementing this constraint is almost trivial:


//checks whether T1 is-a T2
template <class T1, class T2> struct is_a_T2
{
is_a_T2() {constraints();}
static void constraints()
{
T1 t1;
T2& ref=t1; //error if t1 is not a T2
}
};
This constraint may be useful for example in MFC-style frameworks where all classes must be derived from a common base class. Let's test it:

is_a_T2 <C3, S1> t1; //ok, C3 is-a S1
is_a_T2 <S1, S1> t2; //ok
is_a_T2 <S1, C3> t3; //error
is_a_T2 <std::string, S1> t4; //error
is_a_T2 <int, S1> t5; //error
Here's another constraint: "must be an integral type." This one is also easy and can be implemented in many ways. One technique uses the object as an array's index. Since C++ requires that indexes shall be integral types, using any other type will cause a compilation error. I leave the implementation as an exercise to the reader.

Previous Page: Presenting the Problem  
Danny Kalev is a certified system analyst and software engineer specializing in C++ and theoretical aspects of formal languages. He was a member of the C++ standards committee between 1997 and 2000. He recently finished his MA in general linguistics summa cum laude. In his spare time he likes to listen to classical music, read Victorian literature and explore natural languages such as Hittite, Basque and Irish Gaelic. Additional interests include archeology and geology. Danny moderates several C++ forums and contributes regularly to various C++-related sites and magazines. He also gives lectures about programming languages and applied linguistics at academic institutes.
Page 1: IntroductionPage 3: Design Improvements
Page 2: Presenting the Problem 
Please rate this item (5=best)
 1  2  3  4  5
advertisement