【问题标题】:Invalid integer constant expression无效的整数常量表达式
【发布时间】:2011-06-30 02:23:19
【问题描述】:

在这段代码中:

// 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 警告级别 /wall - 最高
警告 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:“操作员新 []”:异常规范与先前的声明不匹配
警告 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<_elem>::do_grouping(void) const':函数未内联
警告 21 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::do_falsename(void) const' : 函数未内联
警告 22 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::do_truename(void) const' : 函数未内联
警告 23 警告 C4710: 'std::string std::numpunct<_elem>::do_grouping(void) const' : 函数未内联
警告 24 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::do_falsename(void) const' : 函数未内联
警告 25 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::do_truename(void) const' : 函数未内联
警告 26 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::falsename(void) const' : 函数未内联
警告 27 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::truename(void) const' : 函数未内联
警告 28 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::falsename(void) const' : 函数未内联
警告 29 警告 C4710: 'std::basic_string<_elem> std::numpunct<_elem>::truename(void) const' : 函数未内联
警告 30 警告 C4710: 'std::string std::numpunct<_elem>::grouping(void) const' : 函数未内联
警告 31 警告 C4710:'std::string std::numpunct<_elem>::grouping(void) const':函数未内联

【问题讨论】:

  • @There:你问了多少关于SO的问题,你还没有学会如何发布完整的错误信息?耻辱。在。你。
  • 使用双下划线定义宏的好方法总有一天会卷土重来。为什么你觉得有必要使用double underscore
  • @Martin 它只是从微软网站support.microsoft.com/kb/155196复制和粘贴的
  • 另请注意额外的 STR1 => STR2(您已删除)才能使 # 正常工作以用于引用目的。跨度>
  • 微软被允许这样做。因为他们构建编译器和操作系统,双下划线实际上是为他们的使用而保留的(在系统和编译器头文件中)。您这样做可能会破坏底层头文件并导致 UB

标签: c++ visual-studio-2010


【解决方案1】:
template<class T, class T1>
struct mismatch
{
    static const bool value; //= is_signed<T>::value && is_signed<T1>::value;
};

除了詹姆斯说的,你为什么评论is_signed&lt;T&gt;::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警告

这里使用类似的技术在编译时打印阶乘:

Calculating and printing factorial at compile time in C++

【讨论】:

  • @Nawaz 是的,它确实有效,我只是想在课外做。不要问为什么;)
  • @James:你淘气:P。反正固定。 :D
  • @我们无能为力:...然后您可以溢出,如此解决方案所示:stackoverflow.com/questions/4977715/…
  • @我们无能为力:...看解决方案的最后一部分!
  • @我们无能为力:请提供更多信息。 1)您使用了哪种解决方案? 2)如果你使用它会发生什么?它给出错误吗? 3) 如果它没有给出错误,编译器不会将Need_to_do_3D_collision_testing 打印为警告? 4) 你到底是怎么使用它的?
【解决方案2】:
#if int(mismatch<T,T1>::value) 

预处理指令在解析源代码之前进行评估。在这个#if 指令中,编译器不知道mismatch&lt;T,T1&gt;::value 是什么。

【讨论】:

  • 如果你的编译器有static_assert(我不记得VS 2010是否有),你可以将它用于条件失败部分。否则,Boost 有BOOST_STATIC_ASSERT
  • @Jeremiah:有点。 OP 的代码生成编译时消息,而不是错误。
  • @James 有没有办法使用宏来评估这个表达式?
  • @James 对您的评论 - 确切地说,它必须是消息而不是错误。 OP 的缩写是什么意思?
  • @There: 不,您不能为此使用宏。 T 是一个模板参数,模板实例化直到预处理完成很久之后才会发生。你的编译器是否提供了一种在预处理后生成非错误编译消息的方法,我不知道。正如@Jeremiah 所说,您可以使用static_assert 断言条件为真(如果不是,则导致编译失败)。 Visual C++ 2010 确实支持static_assert。 “OP”代表“原始帖子”或“原始发帖人”,指的是问题本身或问题的提问者,具体取决于上下文。
猜你喜欢
  • 1970-01-01
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-18
  • 2018-12-02
  • 2018-09-03
相关资源
最近更新 更多