无效的整型常量表达式

时间:2011-02-18 20:39:16

标签: c++ visual-studio-2010

在此代码中:

// 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;
}

我正在追踪错误信息:
C1017:无效的整数常量表达式 为什么?以及如何解决?

被修改

#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;
}

我收到以下警告:
警告1警告C4305:'初始化':从'int'截断到'const char'
警告2警告C4309:'初始化':截断常数值
但不是结构名称的警告。所以它对我来说并不适用 Edit_2 警告级别/墙 - 最高
警告1警告C4820:'_ wfinddata64i32_t':在数据成员'_wfinddata64i32_t :: attrib'之后添加'4'字节填充 警告2警告C4820:'_ wfinddata64i32_t':在数据成员'_wfinddata64i32_t :: name'之后添加'4'字节填充 警告3警告C4820:'_ wfinddata64_t':在数据成员'_wfinddata64_t :: attrib'之后添加'4'字节填充 警告4警告C4820:'_ stat32':在数据成员'_stat32 :: st_gid'之后添加'2'字节填充 警告5警告C4820:'stat':在数据成员'stat :: st_gid'之后添加'2'字节填充 警告6警告C4820:'_ stat32i64':在数据成员'_stat32i64 :: st_gid'之后添加'2'字节填充 警告7警告C4820:'_ stat32i64':在数据成员'_stat32i64 :: st_rdev'之后添加'4'字节填充 警告8警告C4820:'_stat32i64':在数据成员'_stat32i64 :: st_ctime'之后添加'4'字节填充 警告9警告C4820:'_ stat64i32':在数据成员'_stat64i32 :: st_gid'之后添加'2'字节填充 警告10警告C4820:'_ stat64':在数据成员'_stat64 :: st_gid'之后添加'2'字节填充 警告11警告C4820:'_ stat64':在数据成员'_stat64 :: st_rdev'之后添加'4'字节填充警告12警告C4986:'operator new []':异常规范与先前的声明不匹配
警告13警告C4986:'operator delete []':异常规范与先前的声明不符 警告14警告C4820:'type_info':在数据成员'type_info :: _ M_d_name'之后添加'3'字节填充警告15警告C4305:'初始化':从'int'截断到'const char'警告16警告C4309:'初始化':截断常数值
警告17警告C4710:'std :: _ Exception_ptr std :: _ Exception_ptr :: _ Current_exception(void)':函数未内联


警告18警告C4710:'std :: string std :: locale :: name(void)const':函数未内联


警告19警告C4710:'std :: locale std :: ios_base :: getloc(void)const':函数未内联


警告20警告C4710:'std :: string std :: numpunct&lt; _Elem&gt; :: do_grouping(void)const':函数未内联


 警告21警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: do_falsename(void)const':函数未内联


警告22警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: do_truename(void)const':函数未内联


警告23警告C4710:'std :: string std :: numpunct&lt; _Elem&gt; :: do_grouping(void)const':函数未内联


警告24警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: do_falsename(void)const':函数未内联


警告25警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: do_truename(void)const':函数未内联


警告26警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: falsename(void)const':函数未内联


警告27警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: truename(void)const':函数未内联

警告28警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: falsename(void)const':函数未内联


警告29警告C4710:'std :: basic_string&lt; _Elem,_Traits,_Ax&gt; std :: numpunct&lt; _Elem&gt; :: truename(void)const':函数未内联

警告30警告C4710:'std :: string std :: numpunct&lt; _Elem&gt; :: grouping(void)const':函数未内联


警告31警告C4710:'std :: string std :: numpunct&lt; _Elem&gt; :: grouping(void)const':函数未内联

2 个答案:

答案 0 :(得分:6)

#if int(mismatch<T,T1>::value) 

在解析源之前评估预处理指令。在这个#if指令中,编译器不知道mismatch<T,T1>::value是什么。

答案 1 :(得分:0)

template<class T, class T1>
struct mismatch
{
    static const bool value; //= is_signed<T>::value && is_signed<T1>::value;
};

除了詹姆斯所说的,你为什么评论is_signed<T>::value ..?取消注释。它应该工作!


解决方案(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;
}

如果TT1不匹配,那么您会在编译错误中看到字符串Need_to_do_3D_collision_testing


解决方案(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;
}

生成警告而不是错误的解决方案:

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;
}

现在,如果TT1不匹配,那么您会在编辑警告中看到字符串Need_to_do_3D_collision_testing

类似的技术用于在编译时打印factorial:

Calculating and printing factorial at compile time in C++