C++11 makes it quite easy to avoid this pitfall by allowing in-class initialization of non-static data members. For example:
struct foo
{
foo(int i) : i(i) {} // here i will be set to argument value
foo() {} // here i will be zero
int i = {}; // value (zero) initialize i
};
This feature is not restricted to trivial types either. So just start initializing data members as soon you declare them within the class definition.
If your compiler doesn't support this feature, try cranking the warning level up to see if it'll tell you about uninitialized data members. For instance, g++ has the -Weffc++
flag that will warn you about uninitialized data members (amongst other things).
Next thing to try would be a static analysis tool to catch these mistakes.
In conclusion, there are several things I'd try before going down the path of boxing every trivial data type.