constexpr我的库中有几个简短的函数可以执行一些简单的计算.我在运行时和编译时上下文中都使用它们.
我想在这些函数的主体中执行一些断言,但是assert(...)在constexpr函数中无效并且static_assert(...)不能用于检查函数参数.
例:
constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
assert(mMin <= mMax); // does not compile!
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法检查函数是在运行时或编译时常量中执行还是assert只在运行时执行它才执行?
constexpr int getClamped(int mValue, int mMin, int mMax) noexcept
{
assert_if_runtime(mMin <= mMax);
return mValue < mMin ? mMin : (mValue > mMax ? mMax : mValue);
}
Run Code Online (Sandbox Code Playgroud) std::variant 提供以下访问功能:
std::get_if:取指针到variant,返回指针替代.
template <std::size_t I, typename... Ts>
auto* std::get_if(std::variant<Ts...>* pv) noexcept;
Run Code Online (Sandbox Code Playgroud)
如果
pv不是空指针pv->index() == I,则返回指向存储在指向的变量中的值的指针pv.否则,返回空指针值.
这意味着get_if实现大致如下:
template <std::size_t I, typename... Ts>
auto* std::get_if(std::variant<Ts...>* pv) noexcept
{
if(pv == nullptr) return nullptr;
if(pv->index() != I) return nullptr;
return &(pv->real_get<I>());
}
Run Code Online (Sandbox Code Playgroud)std::get:取基准来variant,回到参考替代,throw对非法访问.
template <std::size_t I, typename... Ts>
auto& std::get(std::variant<Ts...>& v);
Run Code Online (Sandbox Code Playgroud)
如果
v.index() == I,则返回对存储的值的引用v.否则,抛出std::bad_variant_access …
我发现了一个代码片段,它在clang ++ 4(和trunk)中编译并正常工作,但无法在g ++ 7(和trunk)中编译.我们假设我有以下struct类型:
struct a { void foo() { } };
struct b { void bar() { } };
struct c { void bar() { } };
Run Code Online (Sandbox Code Playgroud)
我想创建一个过载设定的lambda表达式哪些处理a明确,而b与c被"捕获"用一个通用的λ auto参数:
auto ol = overload([](a x) { x.foo(); },
[](auto x){ x.bar(); })
Run Code Online (Sandbox Code Playgroud)
当我调用时ol(a{}):
铛++编译和行为与预期:a"匹配"的第一拉姆达,而b与c匹配第二个.
g ++无法编译,出现以下错误:
error: 'struct a' has no member named 'bar' …Run Code Online (Sandbox Code Playgroud)我正在制作一个C++游戏,我想让它自动获得用户的桌面分辨率.
到目前为止,我找到了仅限Windows的解决方案 - 是否有方法/库可以在Windows/Mac/Linux上找到解决方案?
template<typename... TArgs> struct List { };
template<template<typename...> class> struct ListHelper;
template<typename T, typename... TArgs> struct ListHelper<List<T, TArgs...>> { };
^
/*Error: Template argument for template template parameter
must be a class template or type alias template*/
Run Code Online (Sandbox Code Playgroud)
怎么了?我正在使用clang ++ SVN.
g ++ 6.1最近被引入到Arch Linux的测试库中,我用g ++ 5.3.0成功编译的一些代码不再编译了.我做了一个最小的例子:
// This code compiles with g++ 5.3.0
// This does not compile with g++ 6.1
#include <type_traits>
#include <utility>
#include <tuple>
#define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)
struct sinker
{
template <typename T>
void sink(T&)
{
}
};
template <typename T, typename TF>
void caller(T& v, TF&& f)
{
sinker s;
f(s, v);
}
template <typename T>
void interface(T& v)
{
return caller(v, [](auto& xs, auto&& xv) -> decltype(auto)
{
xs.sink(FWD(xv));
});
}
int main()
{ …Run Code Online (Sandbox Code Playgroud) 考虑这个例子(也可以在wandbox上使用):
template <template <auto> class>
void test() { }
template <int>
struct X { };
Run Code Online (Sandbox Code Playgroud)
尝试test<X>()在clang++4.0 (主干)上实例化会导致编译错误:
error: no matching function for call to 'test'
test<X>();
^~~~~~~
note: candidate template ignored:
invalid explicitly-specified argument for 1st template parameter
void test() { }
Run Code Online (Sandbox Code Playgroud)
我最初的假设/直觉是test可以用来匹配任何template具有非类型参数的人.
但是,以下代码段成功编译:
template <template <auto> class>
void test() { }
// vvvv
template <auto>
struct X { };
Run Code Online (Sandbox Code Playgroud)
这是有意的吗?在P0127R2中找不到任何结论.
std::experimental::apply 有以下签名:
template <class F, class Tuple>
constexpr decltype(auto) apply(F&& f, Tuple&& t);
Run Code Online (Sandbox Code Playgroud)
它基本上f通过扩展t元素作为参数来调用.
我想要的东西完全相同,但同时有多个元组:
template <class F, class... Tuples>
constexpr decltype(auto) multi_apply(F&& f, Tuples&&... ts);
Run Code Online (Sandbox Code Playgroud)
用法示例:
std::tuple t0{1, 2, 3};
std::tuple t1{4, 5, 6};
auto sum = [](auto... xs){ return (0 + ... + xs); };
assert(multi_apply(sum, t0, t1) == 1 + 2 + 3 + 4 + 5 + 6);
Run Code Online (Sandbox Code Playgroud)
我可以想到各种天真的实施方式multi_apply:
使用std::tuple_cat然后调用std::experimental::apply.
使用递归将每个元组的参数绑定到一系列最终调用原始函数的lambda.
但我要问的是:如何在multi_apply不诉诸std::tuple_cat …
请考虑以下代码段:
void f();
void a() { f(); }
void b() noexcept { f(); }
Run Code Online (Sandbox Code Playgroud)
在上面的场景f中,当前转换单元中的编译器看不到正文.因此,由于b已标记noexcept,因此必须在调用方生成其他代码,以确保捕获并std::terminate调用异常.
这就是clang++ -Ofast -std=c++2a做(主干版本):
a(): # @a()
jmp f() # TAILCALL
b(): # @b()
push rax
call f()
pop rax
ret
mov rdi, rax
call __clang_call_terminate
__clang_call_terminate: # @__clang_call_terminate
push rax
call __cxa_begin_catch
call std::terminate()
Run Code Online (Sandbox Code Playgroud)
但是,g++ -Ofast -std=c++2a不(主干版):
a():
jmp f()
b():
jmp f()
Run Code Online (Sandbox Code Playgroud)
怎么g++逃避这个?不应该在调用方生成代码,因为主体f不可见? …
C ++ 17标准说:
Run Code Online (Sandbox Code Playgroud)polymorphic_allocator(memory_resource* r);
要求:
r非空。效果:设置
memory_rsrc为r。抛出:没事。
[?注意:此构造函数提供的隐式转换
memory_resource*。-?尾注?]
如果“ requires”子句提到必须为非null ,那么接受a memory_resource*而不是a memory_resource&的意义何在?r
彭博(Bloomberg¹)风格指南鼓励接受将要通过指针而不是引用进行突变的参数,以便调用方的“与”号成为可见的突变标记。但是,标准中没有此类先例。
r被视为指针而不是参考的原因是什么?
¹ pmr与重彭博参与规范,因为该公司采用的是多态的分配模式。