假设我有一个模板函数,它接受一个整数和一个const引用到类型为T的实例.现在,根据整数,只有一些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);
}
Run Code Online (Sandbox Code Playgroud)
这只允许i = 0和T = float的组合.对于其他组合,一个好方法是创建一个宏,生成代码为template<> func(const int& i, const …
template<typename T> constexpr inline
T getClamped(const T& mValue, const T& mMin, const T& mMax)
{
assert(mMin < mMax); // remove this line to successfully compile
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
Run Code Online (Sandbox Code Playgroud)
错误:constexpr函数的主体 'constexpr T getClamped(const T&,const T&,const T&)[with T = long unsigned int]' not return-statement
用g++ 4.8.1.clang++ 3.4不抱怨
谁在这?我可以g++在不使用宏的情况下编译代码吗?
这是我的问题.我有一个BINARY_FLAG宏:
#define BINARY_FLAG( n ) ( static_cast<DWORD>( 1 << ( n ) ) )
Run Code Online (Sandbox Code Playgroud)
哪个可以像这样使用("常量"场景):
static const SomeConstant = BINARY_FLAG( 5 );
Run Code Online (Sandbox Code Playgroud)
或者像这样("变量"场景):
for( int i = 0; i < 10; i++ ) {
DWORD flag = BINARY_FLAG( i );
// do something with the value
}
Run Code Online (Sandbox Code Playgroud)
这个宏根本不是万无一失的 - 一个人可以通过-1或34那里,最多会有一个警告,但行为将是未定义的.我想让它变得更加万无一失.
对于常量场景,我可以使用模板:
template<int Shift> class BinaryFlag {
staticAssert( 0 <= Shift && Shift < sizeof( DWORD) * CHAR_BIT );
public:
static const DWORD FlagValue = …Run Code Online (Sandbox Code Playgroud)