Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用静态断言检查传递给宏的类型_C++_C_Visual Studio 2010_G++_Static Assert - Fatal编程技术网

C++ 使用静态断言检查传递给宏的类型

C++ 使用静态断言检查传递给宏的类型,c++,c,visual-studio-2010,g++,static-assert,C++,C,Visual Studio 2010,G++,Static Assert,不幸的是,我的库的原始版本使用了一些非常疯狂的C语言,我还剩下了几个宏。特别是,我有一系列宏,它们希望传递某些类型给它们是否可以按照以下方式进行操作: static_assert(decltype(retval) == bool); 怎么办?有什么聪明的选择吗? 是的,我知道宏是坏的。我知道C++不是C等。 更新0 这是一些,还有一些。欢迎提出建议。原始问题保持不变。免责声明:这是一个糟糕的答案,肯定有更好的解决方案。举个例子:) 它肯定已经被实现了,但是你自己去实现它是微不足道的 templ

不幸的是,我的库的原始版本使用了一些非常疯狂的C语言,我还剩下了几个宏。特别是,我有一系列宏,它们希望传递某些类型给它们是否可以按照以下方式进行操作:

static_assert(decltype(retval) == bool);
怎么办?有什么聪明的选择吗?

是的,我知道宏是坏的。我知道C++不是C等。 更新0 这是一些,还有一些。欢迎提出建议。原始问题保持不变。

免责声明:这是一个糟糕的答案,肯定有更好的解决方案。举个例子:)

它肯定已经被实现了,但是你自己去实现它是微不足道的

template <class T1, class T2> struct CheckSameType; //no definition
template <class T> struct CheckSameType<T,T>{}; //

template <class T1, class T2>
AssertHasType(T2)
{
   CheckSameType<T1, T2> tmp; //will result in error if T1 is not T2
}
模板结构CheckSameType//没有定义
模板结构CheckSameType{}//
模板
资产类型(T2)
{
CheckSameType tmp;//如果T1不是T2,将导致错误
}
要像这样使用:

AssertHasType<bool>(retval);
AssertHasType(retval);
备选方案(GMan建议):

static_assert(decltype(retval) == bool);
模板结构SameType
{
枚举{value=false};
}
模板结构SameType
{
枚举{value=true};
}; 

static_assert(SameType<decltype(retval), bool>::value);
static_断言(SameType::value);

大多数宏都可以替换为
内联函数和/或模板。作为一个例子,过于聪明的参数大小检查Posix
isnan
宏是C++0x中的一个模板。哦,糟糕的例子,但你明白了

该规则的主要例外是基本上实现更高级语言功能的宏。例如,更智能的异常处理、协方差或一组参数化声明

在某些情况下,不能合理地表示为
内联
函数或模板的宏可以用更智能的预处理(即代码生成)来代替。然后在某个地方有一个脚本,可以生成必要的代码。例如,可以用纯宏和模板在纯C++中执行选项类,但是它有毛茸茸的,并且更容易理解,也可能是更可维护的替代,可以使用生成必要的类的脚本,以额外的构建步骤和处理多种语言为代价。
干杯&hth.,

您似乎需要
decltype
,因为您有一个表达式,但想要验证一个类型。现在已经有足够的方法可以做到这一点(C++03)。例如,检查一个bool

inline void mustBeBool(bool) { }
template<typename T> inline void mustBeBool(T t) { & (&t); } // Takes address of rvalue (&t)

// Use:
#define DifficultMacro(B) do { mustBeBool(B); foo(B); } while (false)
inline void mustBeBool(bool){
模板内联void mustBeBool(T){&(&T);}//获取右值(&T)的地址
//使用:
#定义困难宏(B)do{mustBeBool(B);foo(B);}while(false)

我发现使用@suggestion:

#include <type_traits>

static_assert(std::is_same<decltype(retval), bool>::value, "retval must be bool");
#包括
静态断言(std::is_same::value,“retval必须是bool”);

如果您确实关心
常量
volatile
限定符,并且希望确保类型的
常量
volatile
部分也与您要比较的类型完全匹配,请执行以下操作:

这同样适用于
volatile
。如果您也不关心类型的
volatile
部分,可以使用
std::remove\u volatile::type
忽略它:

static_assert(std::is_same<std::remove_volatile<decltype(my_variable)>::type, uint64_t>::value, 
              "type must be `uint64_t` OR `volatile uint64_t`");
static_assert(std::is_same<std::remove_cv<decltype(my_variable)>::type, uint64_t>::value, 
              "type must be `uint64_t` OR `const uint64_t` OR `volatile uint64_t` OR `volatile const uint64_t`");
还请注意,从C++17开始,您可以执行以下操作:

  • std::remove_cv_t
    代替
    std::remove_cv::type
    ,并且:
  • std::is_same_v
    代替
    std::is_same::value
  • 参考资料:
  • -
    std::remove\u cv
    std::remove\u const
    std::remove\u volatile
  • 相关的:
  • [我的另一个答案是使用上述
    static\u assert
    技巧]
  • [我自己的回答]
  • [我自己的问题]
  • *****

  • 回答/概念一点也不错,尽管我不懂
    AssertHasType
    和下面几行的语法。不过,我建议制作元函数和静态断言实用程序,它提供两个可重复使用的实用程序,可以组合起来产生预期效果,而不是针对每个条件进行自定义检查。或者使用
    类型特征
    标题中的
    是相同的
    (我希望VC10可以使用)。为了增强健壮性,你需要一个
    模板的
    地址\u来抓住那些重载一元运算符的白痴
    T::operator&()
    请在你否决投票时提供一个理由。这有助于其他人理解答案的错误。或者,它可以帮助其他人无视否决票。看过代码后,很明显,实际的宏被堆栈分配的对象所替代,大大提高了可靠性和可读性。这些宏被用于函数调用/返回日志。看到实际宏,我强烈建议阅读现代C++设计或[Ex]特殊C++。@ MsAlter:我无法想象C++如何为我的输入/退出提供隐式替代,但我将看看。还要注意,编写一个FS是非常非Meta的,我的目标不是创建一些大的C++框架。任何从作用域中退出的操作都将销毁该对象。因此,在进入时调用ctor,在退出时调用dtor。自动dtor调用特别有用,我们从历史上知道,典型的程序员会错过函数所有出口中约5%的宏。c++03的等价物是什么?@balki:只需升级到c++11即可。C++已经够坏了,不要在自己身上做得更糟:当使用<代码> STD::IS>相同的代码> > >包含< /代码>。关于const /引用限定符?@ EnPoCulm RealStimeMeNICA可以使用<代码> STD::DeaveWyconst ,<代码> STD::ReaveVixRebug < /C> >等。C++ 20也有<代码> STD::ReaveVCVReF。
    static_assert(std::is_same<std::remove_volatile<decltype(my_variable)>::type, uint64_t>::value, 
                  "type must be `uint64_t` OR `volatile uint64_t`");
    
    static_assert(std::is_same<std::remove_cv<decltype(my_variable)>::type, uint64_t>::value, 
                  "type must be `uint64_t` OR `const uint64_t` OR `volatile uint64_t` OR `volatile const uint64_t`");