// A simple type-traits test for void parameter types.
// CS 509, Spring 2002.

#include <iostream>
#include <cstdlib>

// This struct exports a constant boolean value indicating whether or not the
// actual template-parameter type is void.  

template <typename T> 
struct is_void { 
  static const bool void_type = false; 
  };

template <> 
struct is_void<void> { 
  static const bool void_type = true; 
  };


// This parameterless template function, when called, prints one of the two
// messages based on the actual template parameter type.

template <typename T>
static void check_for_void() {

  is_void<T> void_check;

  if (void_check.void_type)
    std::cerr << "Invalid void parameter type.\n";
  else
    std::cerr << "Invalid parameter type ok.\n";
  }


// This template class that must have a non-void actual parameter type.  The
// constructor calls check_for_void() (note the funky call syntax) to make
// sure.

template <typename T>
struct needs_nonvoid {
  needs_nonvoid() {
    check_for_void<T>();
    }
  };


int main() {
  needs_nonvoid<int> ok;
  needs_nonvoid<void> bad;
  }


syntax highlighted by Code2HTML, v. 0.9