我想通过使用constexpr
函数而不是多个constexpr
if
分支来简化代码。
这是带有旧代码注释的代码
旧代码使用msvc
(vs 2017使用c++17
)和clang
(android ndk r20
)进行编译,但是在{{1 }}在clang 8
中!
并且新代码既不能用windows x64
也不能用visual studio
编译
msvc
新代码无法在此行中编译:
clang
msvc的错误代码是:
template <class T>
constexpr bool IsValueNegative(T value) // this function should be evaluated at runtime but it it isn't !
{
if constexpr (std::is_integral_v<T>) // SOCKET = ULONG_PTR and linux handles are int
{
return value < 0;
}
else // HANDLE = void * and most other handles are pointers
{
return (intptr_t)value < 0;
}
}
template <class T, const T null_value, bool no_negative = true>
class HandleWrapper
{
public:
HandleWrapper() : handle(null_value)
{}
HandleWrapper(T h) : handle(h)
{
if constexpr (no_negative) // to convert INVALID_HANDLE_VALUE to nullptr
{
if constexpr (!IsValueNegative(null_value)) // SOCKET invalid handle is -1
{
if (IsValueNegative(handle)) //
handle = null_value;
}
/*
if constexpr (std::is_integral_v<T>)
{
if constexpr (null_value >= 0)
{
if (handle < 0)
handle = null_value;
}
}
else
{
if constexpr ((intptr_t)null_value >= 0) // clang 8 can't compile this , don't know why
{
if ((intptr_t)handle < 0)
handle = null_value;
}
}
*/
}
}
private:
T handle;
};
template <class T, const T null_value, bool no_negative, auto Deleter>
struct HandleHelper
{
using pointer = HandleWrapper<T, null_value, no_negative>;
void operator()(pointer p)
{
if constexpr (!no_negative)
{
if (!IsValueNegative(null_value) && IsValueNegative(T(p))) // pseudo handle from GetCurrentProcess or GetCurrentThread
return;
}
/*
if constexpr (!no_negative && )
{
if ((uintptr_t)T(p) <= 0)
{
std::cout << "[*] this is a pseudo handle\n";
return;
}
}
*/
Deleter(T(p));
}
};
using Handle = std::unique_ptr<HandleWrapper<HANDLE, nullptr, true>, HandleHelper<HANDLE, nullptr, true, CloseHandle>>;
using ProcessHandle = std::unique_ptr<HandleWrapper<HANDLE, nullptr, false>, HandleHelper<HANDLE, nullptr, false, CloseHandle>>;
using ThreadHandle = ProcessHandle;
和从c 8:
if constexpr (!IsValueNegative(null_value)) // SOCKET invalid handle is -1
但是所有null值在编译时都是已知的
答案 0 :(得分:4)
运行时,Clang给出此错误:
note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
return (intptr_t)value < 0;
投射指向整数类型的指针不是常量表达式(因为它是reinterpret_cast
),因此不能使用if constexpr
。