gpt4 book ai didi

c++ - 如果可能的话静态断言,否则动态断言?

转载 作者:可可西里 更新时间:2023-11-01 15:18:23 24 4
gpt4 key购买 nike

假设我有一个模板函数,它接受一个整数和一个对类型 T 实例的 const 引用。现在根据整数,只有一些 T 是可接受的,否则在运行时会抛出异常。

如果此函数的所有使用都使用常量整数,则可以将 int 设为模板参数并使用静态断言来检查它是否可接受。所以而不是 func(1,c)一个人会使用 func<1>(c)并将获得编译时类型检查。有没有办法写func(1,c)并且仍然保持编译时检查,同时还能够编写 func(i,c)并使用动态断言?目标是使其对开发人员透明。如果添加这种安全性而不用为编译时常量之类的事情打扰开发人员,那就太好了。他们可能只记得 func(1,c)始终有效并使用它,避免检查。

如何尽可能使用静态断言定义函数,否则使用动态断言?


以下代码显示了 Ivan Shcherbakov 的 GCC 解决方案:

#include <iostream>
#include <cassert>

template<typename T>
void __attribute__((always_inline)) func(const int& i, const T& t);

void compile_time_error_() __attribute__((__error__ ("assertion failed")));

template<>
void __attribute__((always_inline))
func(const int& i, const float& t)
{
do {
if (i != 0) {
if (__builtin_constant_p(i)) compile_time_error_();
std::cerr << "assertion xzy failed" << std::endl;
exit(1);
}
} while (0);
func_impl<float>(i,t);
}

这将只允许 i=0 和 T=float 的组合。对于其他组合,一个好方法是创建一个生成代码 template<> func(const int& i, const T& t) 的宏。替换为 T 和 i != 0。

最佳答案

好吧,如果你使用的是 GCC,你可以使用一个肮脏的 hack,但它只有在启用函数内联(-O1 或更多)时才有效:

void my_error() __attribute__((__error__ ("Your message here")));

template <typename T1, typename T2> struct compare_types
{
enum {Equals = 0};
};

template <typename T1> struct compare_types<T1,T1>
{
enum {Equals = 1};
};

template <typename Type> __attribute__((always_inline)) void func(int a, Type &x)
{
if (__builtin_constant_p(a))
{
if (a == 1 && compare_types<Type,char>::Equals)
my_error();
}
}

在这种情况下,当 a == 1Typechar 时,您将收到错误消息。这是一个将触发它的示例:

int main()
{
char x;
func(1, x);
return 0;
}

请注意,此示例严重依赖于特定于 gcc 的 __builtin_constant_p() 函数,无法与其他编译器一起使用!

关于c++ - 如果可能的话静态断言,否则动态断言?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11441302/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com