我string_view为C++ 14项目编写了一个轻量级的包装器,并且在MSVC 2017中它static_assert在编译时触发,但是在运行时相同的代码传递了常规assert.我的问题是,这是一个编译器错误,显示未定义的行为,还是完全不同的东西?
这是蒸馏代码:
#include <cassert> // assert
#include <cstddef> // size_t
class String_View
{
char const* m_data;
std::size_t m_size;
public:
constexpr String_View()
: m_data( nullptr ),
m_size( 0u )
{}
constexpr char const* begin() const noexcept
{ return m_data; }
constexpr char const* end() const noexcept
{ return m_data + m_size; }
};
void static_foo()
{
constexpr String_View sv;
// static_assert( sv.begin() == sv.end() ); // this errors
static_assert( sv.begin() == nullptr ); …Run Code Online (Sandbox Code Playgroud) 是否有符合C++标准的方法来确定编译时(或运行时,作为替代)的'float','double'和'long double'的结构?
如果我假设,std::numeric_limits< T >::is_iec559 == true并且std::numeric_limits< T >::radix == 2我怀疑可以通过以下规则:
用下面的表达式模糊地说:
size_t num_significand_bits = std::numeric_limits< T >::digits;size_t num_exponent_bits = log2( 2 * std::numeric_limits< T >::max_exponent );size_t num_sign_bits = 1u;除了我知道
std::numeric_limits< T >::digits 包括"整数位",无论格式是否实际明确表示它,所以我不知道如何以编程方式检测和调整.std::numeric_limits< T >::max_exponent是永远的2^(num_exponent_bits)/2.背景:我试图解决两个问题:
在我最近写的一个程序中,我希望在我的"业务逻辑"代码在第三方或项目API中触发异常时进行记录.(为了澄清,我想在使用API导致异常时进行记录.这可能比实际高出许多帧throw,并且可能比实际低很多帧catch(可以发生异常有效负载的记录).)我做了以下:
void former_function()
{
/* some code here */
try
{
/* some specific code that I know may throw, and want to log about */
}
catch( ... )
{
log( "an exception occurred when doing something with some other data" );
throw;
}
/* some code here */
}
Run Code Online (Sandbox Code Playgroud)
简而言之,如果发生异常,请创建一个catch-all子句,记录错误并重新抛出.在我看来,这是安全的.我知道一般来说,catch-all被认为是错误的,因为根本没有对异常的引用来获取任何有用的信息.但是,我只是要重新抛出它,所以什么都不会丢失.
现在,它本身很好,但其他一些程序员修改了这个程序,最终违反了上述规定.具体来说,他们在一个案例中将大量代码放入try-block,在另一个案例中删除了'throw'并放置了'return'.
我现在看到我的解决方案很脆弱; 这不是未来修改的证据.
我想要一个没有这些问题的更好的解决方案.
我有另一个没有上述问题的潜在解决方案,但我想知道别人怎么想.它使用RAII,特别是一个"Scoped Exit"对象,如果在构造时std::uncaught_exception 不是真的则隐式触发,但在破坏时是真的:
#include <ciso646> // not, and
#include <exception> // uncaught_exception
class ExceptionTriggeredLog
{
private: …Run Code Online (Sandbox Code Playgroud) 所有,
为什么以下代码无法为'std :: endl'编译,但它适用于所有其他插入类型?
#include <sstream> // ostringstream
/// @brief A class that does streamed, formatted output via 'operator<<'.
class My_Stream
{
public:
/// @brief A member method that manipulates the underlying stream.
void foo()
{
m_oss << "foo_was_here; ";
}
private:
/// @brief The underlying stream.
std::ostringstream m_oss;
/// @brief 'operator<<' is a friend.
template< typename T >
friend My_Stream& operator<<( My_Stream& a_r_my_stream,
const T& a_r_value );
};
/// @brief A manipulator that calls a class method.
My_Stream& manipulator_foo( …Run Code Online (Sandbox Code Playgroud) 我有一个代码示例,当结构化为类变量时,直接优化不起作用,但作为局部变量起作用; 我想知道:为什么优化不会发生在类变量公式上?
我的示例代码的目的是让一个类在构造时启用或禁用,并且可能在它的生命周期内更改.我希望,当对象的整个生命周期被禁用时,编译器会优化掉在启用对象时有条件执行的所有代码.
具体来说,我有一个std :: ofstream,我只想在"启用"时写入.禁用时,我希望跳过所有格式化输出.(我真正的课程是自己的,非平凡的消息格式化.)
我发现当我把它表示为一个类时,我没有得到我期望的优化.但是,如果我将代码全部复制为局部变量,我确实看到了预期的行为.
另外,我发现如果我不在示例类的方法体中的任何地方进行std :: ofstream调用,如'open','exceptions'或'clear',我也会得到预期的优化.(但是,我的设计需要在std :: ofstream上进行这样的调用,所以对我来说这是一个没有实际意义的点.)下面的代码使用MACRO DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR来允许人们尝试这种情况.
我的示例代码使用'asm'表达式将注释插入生成的汇编代码中.如果在程序集中检查编译器的输出,我希望在'disabled-test'注释之间没有汇编.我正在观察'class disabled-test'注释之间的汇编,但是'locals disabled-test'注释之间没有汇编.
输入C++代码:
#include <fstream> // ofstream
#define DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR 0
class Test_Ofstream
{
public:
Test_Ofstream( const char a_filename[],
bool a_b_enabled )
#if DISABLE_OPEN_OFSTREAM_AFTER_CONSTRUCTOR
: m_ofstream( a_filename ),
m_b_enabled( a_b_enabled )
{
}
#else
: m_ofstream(),
m_b_enabled( a_b_enabled )
{
m_ofstream.open( a_filename );
}
#endif
void write_test()
{
if( m_b_enabled )
{
m_ofstream << "Some text.\n";
}
}
private:
std::ofstream m_ofstream;
bool m_b_enabled;
};
int main( int …Run Code Online (Sandbox Code Playgroud) c++ ×5
c++14 ×1
class ×1
compiler-bug ×1
exception ×1
ieee-754 ×1
iostream ×1
local ×1
logging ×1
manipulators ×1
optimization ×1
portability ×1
raii ×1
variables ×1