仅用于编译时参数禁用函数

Disable function only for compile-time argument

本文关键字:函数 参数 用于 编译      更新时间:2023-10-16

我想为任何编译时评估的参数(文字或来自constexpr表达式带来的内容(禁用一个函数。这可能吗?

对于整数,可以使用相反的使用非类型模板参数,但这也会更改呼叫语法。

我正在与严格的整数一起玩,这需要以某种方式启动。处理不良输入的当前规则:

  • 如果仅在运行时知道源值,而变窄的铸件会破坏解释(而不是位(,则抛出一个例外

  • 如果源值在编译时已知,并且不适合源值,则应该有汇编错误。

我的想法是禁用接受所有constexpr参数的构造函数。

严格,我的意思是只允许具有价值的转换:

假设n> = m

  • int<M> to int<N>始终确定
  • uint<M> to uint<N>始终确定

其他所有内容:

  1. 如果源值在编译时已知,则应存在汇编误差。
  2. 如果在编译过程中未知值,请查看转换是否正常工作,否则会引发异常。

对于情况(1(,使用constexpr-throw技巧不起作用:考虑以下(非constexpr上下文(:

// Will compile, but it shouldn't. Instead of not compiling it will throw an exception.
int<16> foo(12345); 
// Will compile. Whatever the type of some_value_from_outside is, 
// check that it fits at runtime. If it does not, throw an exception.
int<16> thisIsFine(some_value_from_outside);

理想是与ConstexPr参数的分辨率不存在,因此我正在尝试找到最佳的解决方法。

我想禁用任何编译时评估参数

的函数

这是不可能的,而且(通常(是没有意义的。

在实践中,使用AS-IF规则,大多数优化编译器将生成f(2);{ int i=2; f(i); }相同代码,因为两者都具有相同的语义。

使用GCC和Clang,您可以使用__builtin_constant_p

使用GCC,您可能会花费数周或几个月的时间来编码GCC插件,该插件将检测(并发出诊断(调用以使用编译时间参数来函数的调用(例如,您可以在插件中实现新功能属性(。但这不会改变过载或打字规则。而且我真的不建议您在特定情况下制作插件。

您的问题不清楚,看来您想要C 没有提供的东西。BTW int<16>不是合法的C ,因为int不是模板。也许您想要std::int16_t

您是否考虑过其他方法,也许是从其他方面生成C 代码,也许使用其他一些预处理器(例如GPP或M4(或C 代码生成器(也许是您自己的QT MOC或GNU BISON或SWIG可能是鼓舞人心的(。

我现在接受,现在有可能检查表达式是constexpr,既不是通过过载(可能很有趣(或任何其他方法。但是,对于参考,我应该在此处列出当前的解决方法:

  1. 将常数称为constexpr,并使用以下习惯

    value fits in type ? cast to type : throw CastException
    

    此Will仅在类型中拟合时才编译,因为否则该函数不是constexpr。

  2. 使用提到的C 编译时检查功能参数的替代模板方法。

我会选择(1(,因为它不需要constexpr案例的不同语法。另外,我认为无论如何命名常数是一个好习惯。