C++ 替换此宏

C++ 替换此宏,c++,macros,template-meta-programming,C++,Macros,Template Meta Programming,考虑到这个宏 #define MAKE_TYPE(_a, _b, _c, _d) ((_a) | ((_b) << 8) | ((_c) << 16) | ((_d) << 24)) #定义MAKE_类型(_a,_b,_c,_d)((_a)|((_b),如果您知道输入是char*: template <class RT> RT MakeType( const char * _arg ) { return _arg[3] | (_arg[2]

考虑到这个宏

#define MAKE_TYPE(_a, _b, _c, _d) ((_a) | ((_b) << 8) | ((_c) << 16) | ((_d) << 24))

#定义MAKE_类型(_a,_b,_c,_d)((_a)|((_b),如果您知道输入是
char*

template <class RT> RT MakeType( const char * _arg )
{
  return _arg[3] | (_arg[2] << 8) | (_arg[1] << 16) | (_arg[0] << 24);
}
模板RT MakeType(常量字符*_参数)
{

return _arg[3]|(_arg[2]错误消息的意思是:数组不能出现在常量表达式中

模板表达式必须是常量表达式,因此数组不能位于模板参数中

您可以有一个指向数组的指针,但这不是您想要的

啊,因为限制只有四个字符,所以可以在单引号中使用多字符常量,例如
'ABCD'
。但是,字符的顺序是由实现定义的


另一件您似乎正在尝试的事情是从字符常量生成类本身的名称。如果您将裸字母而不是字符文本传递到宏中,这是可能的,但是,事实上不是这样。即使它工作正常,也会非常糟糕。

您可以使用多字符常量,例如
 int-four='four'
。但行为是特定于编译器的。

您是否尝试了更多的括号和/或强制转换

#define MAKE_TYPE(s) (int((s)[3]) | (int((s)[2]) << 8) | (int((s)[1]) << 16) | (int((s)[0]) << 24))

#定义MAKE_类型(int((s)[3])|(int((s)[2])像这样的东西怎么样

template <typename T>
typename boost::enable_if_c<(T('1234')==0x31323334), T>::type
make(T v)
{
    return v;
}

const int value = make('ABCD');
模板
typename boost::启用\u if_c::type
制造(电视)
{
返回v;
}
常量int值=make('ABCD');
这是多字符常量的编译器相关行为的安全网。您可以为不同的编译器行为添加进一步的实现,根据需要切换字节。这假定每个编译器的
'1234'
计算的字节顺序是一致的


模板专家可能能够改进。

正如其他人所说,您实际上无法做到这一点,但模板版本中的错误消息会产生误导,因为您编写了
char[4]s
您的意思是
char[4]
。它仍然无法解决此问题,但您会得到一些错误,告诉您实际问题是什么,而不是不相关的语法错误:-)。除了
char s[4]
之外,如果您想提供“ABCD”作为名称,它应该读为
char s[5]
:)当然可以,因为空值使它成为[5]。已决定用另一种方法解决此问题。谢谢大家的帮助。这不会在编译时进行计算。因此,宏的好处将丢失。@xtofl:如果使用引用,变量将不会被复制。@Naszta:我知道。但是在这种情况下,在堆栈上推送引用的成本是推送值的四倍。。。(在32位上。在64位上,可能是8倍。)如果坚持要传递引用,请传递常量:不允许函数更改实际参数。
inline
不会有任何区别。通过编译时咨询,
结果的值在编译时计算,因此它的行为类似于常量值,并且没有运行时开销与之关联。在此处使其内联可以避免函数调用,但结果仍在运行时计算。@Naveen:否。结果将在运行时计算。有关预处理器的详细信息:谢谢,我找到了另一种解决方案。抱歉,我以为它满足了我的要求。结果表明其他方法是正确的。无法分配常数。
template <class T, class RT> RT MakeType( const T &B0, const T &B1, const T &B2, const T &B3 )
{
  return B3 | (B2 << 8) | (B1 << 16) | (B0 << 24);
}
inline unsigned int MakeType( const char * _arg )
{
  return _arg[3] | (_arg[2] << 8) | (_arg[1] << 16) | (_arg[0] << 24);
}
#define MAKE_TYPE(s) (int((s)[3]) | (int((s)[2]) << 8) | (int((s)[1]) << 16) | (int((s)[0]) << 24))
template <typename T>
typename boost::enable_if_c<(T('1234')==0x31323334), T>::type
make(T v)
{
    return v;
}

const int value = make('ABCD');