Invalid integer constant expression
In this code:
// CompileTimeWarnings.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <type_traits>
using namespace std;
#define __STR1__(x) #x
#define __LOC__ __FILE__ "("__STR1__(__LINE__)") : warning : "
// collisions.cpp
template<class T, class T1>
struct mismatch
{
//enum {value = is_signed<T>::value && is_signed<T1>::value};
static const bool value; //= is_signed<T>::value && is_signed<T1>::value;
};
template<class T, class T1>
bool mismatch<T,T1>::value = is_signed<T>::value && is_signed<T1>::value;
template<class T>
struct Int
{
};
template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
#if int(mismatch<T,T1>::value)
#pragma message(__LOC__"Need to do 3D collision testing")
#endif
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
Int<int> a;
Int<signed> b;
b + a;
return 0;
}
I'm getting following err msg:
C1017: Invalid integer constant expression. Why? And how to solve it?Edited
#include "stdafx.h"
#include <type_traits>
#include <iostream>
using namespace std;
template<class T>
struct Int
{
};
template<class T, class T1>
struct Mismatch
{
static const bool value = (!is_signed<T>::value && is_signed<T1>::value) ||
(is_signed<T>::value && !is_signed<T1>::value);
};
template<bool b> struct Need_to_do_3D_collision_testing
{
static void f()
{ static const char value=256; }
};
template<> struct Need_to_do_3D_collision_testing<true>
{
static void f() { }
};
template<class T, class T1> int operator+(Int<T> t, Int<T1> t1)
{
Need_to_do_3D_collision_testing<!Mismatch<T,T1>::value>::f();
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
Int<char> a;
Int<unsigned char> b;
b + a;
return 0;
}
I'm getting following warnings:
Warning 1 warning C4305: 'initializing' : truncation from 'int' to 'const char' Warning 2 warning C4309: 'initializing' : truncation of constant value but not the warning with struct name. So it doesn't work for me as it should. Edit_2 Warning level /wall - highest Warning 1 warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::attrib' Warning 2 warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::name' Warning 3 warning C4820: '_wfinddata64_t' : '4' bytes padding added after data member '_wfinddata64_t::attrib' Warning 4 warning C4820: '_stat32' : '2' bytes padding added after data member '_stat32::st_gid' Warning 5 warning C4820: 'stat' : '2' bytes padding added after data member 'stat::st_gid' Warning 6 warning C4820: '_stat32i64' : '2' bytes padding added after data member '_stat32i64::st_gid' Warning 7 warnin开发者_运维百科g C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_rdev' Warning 8 warning C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_ctime' Warning 9 warning C4820: '_stat64i32' : '2' bytes padding added after data member '_stat64i32::st_gid' Warning 10 warning C4820: '_stat64' : '2' bytes padding added after data member '_stat64::st_gid' Warning 11 warning C4820: '_stat64' : '4' bytes padding added after data member '_stat64::st_rdev' Warning 12 warning C4986: 'operator new[]': exception specification does not match previous declaration Warning 13 warning C4986: 'operator delete[]': exception specification does not match previous declaration Warning 14 warning C4820: 'type_info' : '3' bytes padding added after data member 'type_info::_M_d_name' Warning 15 warning C4305: 'initializing' : truncation from 'int' to 'const char' Warning 16 warning C4309: 'initializing' : truncation of constant value Warning 17 warning C4710: 'std::_Exception_ptr std::_Exception_ptr::_Current_exception(void)' : function not inlined Warning 18 warning C4710: 'std::string std::locale::name(void) const' : function not inlined Warning 19 warning C4710: 'std::locale std::ios_base::getloc(void) const' : function not inlined Warning 20 warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void) const' : function not inlined Warning 21 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_falsename(void) const' : function not inlined Warning 22 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_truename(void) const' : function not inlined Warning 23 warning C4710: 'std::string std::numpunct<_Elem>::do_grouping(void) const' : function not inlined Warning 24 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_falsename(void) const' : function not inlined Warning 25 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::do_truename(void) const' : function not inlined Warning 26 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::falsename(void) const' : function not inlined Warning 27 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::truename(void) const' : function not inlined Warning 28 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::falsename(void) const' : function not inlined Warning 29 warning C4710: 'std::basic_string<_Elem,_Traits,_Ax> std::numpunct<_Elem>::truename(void) const' : function not inlined Warning 30 warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const' : function not inlined Warning 31 warning C4710: 'std::string std::numpunct<_Elem>::grouping(void) const' : function not inlined#if int(mismatch<T,T1>::value)
Preprocessing directives are evaluated before the source is parsed. In this #if
directive, the compiler has no idea what a mismatch<T,T1>::value
is.
template<class T, class T1>
struct mismatch
{
static const bool value; //= is_signed<T>::value && is_signed<T1>::value;
};
Beside what James said, why did you comment is_signed<T>::value ..
? Uncomment that. It should work!
Solution (C++03):
template<bool b> struct static_assert;
template<> struct static_assert<true>{};
template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
static_assert<!mismatch<T,T1>::value> Need_to_do_3D_collision_testing;
return 0;
}
If T
and T1
mismatch, then you would see the string Need_to_do_3D_collision_testing
in the compilation error!
Solution (C++0x):
template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
static_assert(!mismatch<T,T1>::value, "Need to do 3D collision testing");
return 0;
}
Solution that generates warning instead of error:
template<bool b> struct Need_to_do_3D_collision_testing
{
static void f() { static const char value=256; }
};
template<> struct Need_to_do_3D_collision_testing<true>
{
static void f() { }
};
template<class T, class T1>
int operator+(Int<T> t, Int<T1> t1)
{
Need_to_do_3D_collision_testing<!mismatch<T,T1>::value>::f();
return 0;
}
Now, if T
and T1
mismatch, then you would see the string Need_to_do_3D_collision_testing
in the compilation warning!
Similar techniques is used to print factorial at compile time here:
Calculating and printing factorial at compile time in C++
精彩评论