// ------------------
// ClassVariables.c++
// ------------------

#include <cassert>  // assert
#include <iostream> // cout, endl
#include <string>   // string

int f (int i) {
	return i;}

template <typename T>
struct A {
    static T sv0;
    static T sv1;
//  static T sv2  = 2;         // error: ISO C++ forbids in-class initialization of non-const static member "A<T>::sv2"


    static const T scv0;
//  static const T scv1 = 1;   // error: ISO C++ forbids initialization of member constant "A<double>::scv1" of non-integral type "const double"

    static const int scv2 = 2;

    enum {ev = 3};};

template <typename T>
T A<T>::sv0;

template <typename T>
T A<T>::sv1 = f(1);

//template <typename T>        // error: uninitialized const "A<T>::scv0"
//const T A<T>::scv0;

template <typename T>
const T A<T>::scv0 = f(0);

template <typename T>
const int A<T>::scv2;

int main () {
    using namespace std;
    cout << "ClassVariables.c++" << endl;

    {
    assert(A<int>::sv0    == 0);
    assert(A<double>::sv0 == 0);
//  assert(&A<int>::sv0 != &A<double>::sv0);   // error: comparison between distinct pointer types "int*" and "double*" lacks a cast
    }

    {
    assert(A<int>::sv1    == 1);
    assert(A<double>::sv1 == 1);
//  assert(&A<int>::sv0 != &A<double>::sv0);   // error: comparison between distinct pointer types "int*" and "double*" lacks a cast
    }

    {
    assert(A<int>::scv0    == 0);
    assert(A<double>::scv0 == 0);
//  assert(&A<int>::scv0 != &A<double>::scv0); // error: comparison between distinct pointer types "int*" and "double*" lacks a cast
	}

	{
    assert(A<int>::scv2    == 2);
    assert(A<double>::scv2 == 2);
    assert(&A<int>::scv2 != &A<double>::scv2);
    }

    {
    assert(A<int>::ev    == 3);
    assert(A<double>::ev == 3);
    }

    cout << "Done." << endl;
    return 0;}


syntax highlighted by Code2HTML, v. 0.9.1