当您使用浮点数( 、float、double类型long double)进行操作时,是否可以检测到精度损失?说:
template< typename F >
F const sum(F const & a, F const & b)
{
F const sum_(a + b);
// The loss of precision must be detected (here or one line above) if some fraction bit is lost due to rounding
return sum_;
}
Run Code Online (Sandbox Code Playgroud)
特别感兴趣的是x87 FPU 出现在目标架构上,但例程不干预asm纯 C++ 代码的情况。如果有的话,也接受C++11或gnu++11特定功能。
我想创建泛型类模板,在内部使用特定容器来确定不同的类型.像这样的东西:
#include <vector>
#include <list>
template< typename F, template< class ... > class container_type = std::vector >
struct C
{
C();
template< typename U >
C(container_type< U >);
C(container_type< F >);
C(container_type< int >);
container_type< double > param;
};
C< unsigned, std::list > c;
Run Code Online (Sandbox Code Playgroud)
这种方式最自然的方法是什么?比如说,您是否想以任何形式提及容器的分配器的存在?
我想int通过r-或l-值(const)引用将参数(某些具体类型,例如)传递给成员函数.我的解决方案是:
#include <type_traits>
#include <utility>
struct F
{
using desired_parameter_type = int;
template< typename X, typename = typename std::enable_if< std::is_same< typename std::decay< X >::type, desired_parameter_type >::value >::type >
void operator () (X && x) const
{
// or even static_assert(std::is_same< typename std::decay< X >::type, desired_parameter_type >::value, "");
std::forward< X >(x); // something useful
}
};
Run Code Online (Sandbox Code Playgroud)
另一个例子是http://pastebin.com/9kgHmsVC.
但它太冗长了.如何以更简单的方式做到这一点?
也许我应该使用叠加std::remove_reference而std::remove_const不是std::decay,但这里只是简化.
有没有一种方法可以在类似C的结构中执行自动字段重新排序?我的意思是使用语言功能(例如C和C ++的预处理器以及C ++的模板/类型特征/ etc),这使得可以执行以下宏(类似于Boost.Fusion的样式来适应结构):
REARRANGE(StructureName,
(int8_t)(FieldName1),
(int32_t)(FieldName2),
(int16_t)(FieldName3),
(int32_t)(FieldName4));
// is equivalent to (without loss of generality):
struct StructureName
{
int32_t FieldName2;
int32_t FieldName4;
int16_t FieldName3;
int8_t FieldName1;
};
Run Code Online (Sandbox Code Playgroud)
当然,方法应考虑字段的alignof值(以及sizeof),并在可能的情况下考虑#pragma pack当前值。
我知道结果的可移植性很差,但这仅用于本地使用。
必须将字段名称以及相应的类型保存在一起。
目的是减小总结构尺寸。
最近,我试图彻底改造范围后卫通过std::unique_ptr(注:缺失者有成员类型定义pointer-是的特殊处理情况下std::unique_ptr):
#include <type_traits>
#include <utility>
#include <memory>
#include <iostream>
#include <cstdlib>
#include <cassert>
namespace
{
template< typename lambda >
auto
make_scope_guard(lambda && _lambda)
{
struct lambda_caller
{
using pointer = std::decay_t< lambda >;
void
operator () (lambda & l) const noexcept
{
std::forward< lambda >(l)();
}
};
return std::unique_ptr< std::decay_t< lambda >, lambda_caller >(std::forward< lambda >(_lambda));
}
}
int
main()
{
std::cout << 1 << std::endl;
{
std::cout …Run Code Online (Sandbox Code Playgroud) 我尝试稍微修改一下文章中的示例:
#include <iostream>
#include <cfenv>
#pragma STDC FENV_ACCESS ON
int main()
{
std::feclearexcept(FE_ALL_EXCEPT);
//int r = std::feraiseexcept(FE_UNDERFLOW | FE_DIVBYZERO);
double x = 1.0;
double y = 0.0;
double result{};
asm volatile ("fldl %1\n"
"fdivl %2\n" : "=%t"(result) : "m"(x), "m"(y) : "memory");
std::cout << result << std::endl;
int e = std::fetestexcept(FE_ALL_EXCEPT);
if (e & FE_DIVBYZERO) {
std::cout << "division by zero\n";
}
if (e & FE_INEXACT) {
std::cout << "inexact\n";
}
if (e & FE_INVALID) {
std::cout << "invalid\n"; …Run Code Online (Sandbox Code Playgroud) 让我们考虑以下示例:
#include <type_traits>
#if 1
struct X {};
struct O
{
O(X) { ; }
};
#else
struct O {};
struct X
{
operator O () { return {}; }
};
#endif
static_assert(std::is_convertible< X, O >::value);
struct S
{
void f(X) const { ; }
void f(O) { ; }
};
#include <cstdlib>
int
main()
{
S s;
s.f(X{});
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
它给出了一个错误:
error: call to member function 'f' is ambiguous
Run Code Online (Sandbox Code Playgroud)
当我删除const-qualifier时,错误就不复存在了.如果我将const-qualifier 添加到第二次重载,同样会发生同样的情况f.即如果两个过载都是同等的 …
为什么没有歧义?
struct B {};
struct C {};
struct A
{
A(B const &, C const &) {}
A(B const &&, C const &&) = delete;
#if 0
A(B const &, C const &&) = delete;
A(B const &&, C const &) = delete;
#endif
};
B const b() { return {}; } // const result type may make sense
C const c() { return {}; } // for some user-defined types
int main()
{
A a0{B{}, C{}}; // I want …Run Code Online (Sandbox Code Playgroud) 现代 C++ 中有[[likely]]和属性。G++ 和 clang++ 中[[unlikely]]都有相应的__builtin_expect(x, 1)内置函数。__builtin_expect(x, 0)但也有__builtin_unpredictable(x)和__builtin_expect_with_probability(x, 1, 0.5)或(同样)__builtin_expect_with_probability(x, 0, 0.5)内置函数,它告诉编译器防止 CPU 用来自(错误)预测分支的指令填充管道,因为从错误预测路径刷新+恢复管道的成本在统计上大于执行 w/o完全是投机执行。
在和分支上使用[[likely]]或同样[[unlikely]]使用属性(如以下代码片段所示)是否等同于使用假设属性?ifelse[[unpredictable]]
if (x) [[likely]] {
// "if" branch
} else [[likely]] {
// "else" branch
}
Run Code Online (Sandbox Code Playgroud)
或者
if (x) [[unlikely]] {
// "if" branch
} else [[unlikely]] {
// "else" branch
}
Run Code Online (Sandbox Code Playgroud)
据我所知,如果存在,if则编译器默认将分支视为默认情况,如果不存在(因为它通常是从当前函数提前退出的不愉快路径检查的形式)。因此,如果我只是省略任何一个属性,那么它并不等同于指定假设属性。[[likely]]else[[unlikely]]else[[unpredictable]]
c++ compiler-optimization speculative-execution branch-prediction c++-attributes
c++ ×9
c++11 ×5
c++14 ×4
a-star ×1
algorithm ×1
alignment ×1
c ×1
constructor ×1
g++ ×1
gcc ×1
geometry ×1
lambda ×1
overloading ×1
path-finding ×1
pragma ×1
sfinae ×1
struct ×1
unique-ptr ×1