小编Vit*_*meo的帖子

如何在C++中使用static_assert用于constexpr函数参数?

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)

c++ assert constexpr c++11

11
推荐指数
3
解决办法
2212
查看次数

访问`std :: variant`的不安全,"noexcept"和无开销方式

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 …

c++ variant c++17

11
推荐指数
1
解决办法
354
查看次数

使用模板调用操作符和泛型lambdas重载结构 - gcc vs clang

我发现了一个代码片段,它在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明确,而bc被"捕获"用一个通用的λ auto参数:

auto ol = overload([](a x)   { x.foo(); },
                   [](auto x){ x.bar(); })
Run Code Online (Sandbox Code Playgroud)

当我调用时ol(a{}):

  • 铛++编译和行为与预期:a"匹配"的第一拉姆达,而bc匹配第二个.

  • g ++无法编译,出现以下错误:

    error: 'struct a' has no member named 'bar' …
    Run Code Online (Sandbox Code Playgroud)

c++ lambda overloading language-lawyer c++17

11
推荐指数
1
解决办法
579
查看次数

在C++中以便携式方式获取桌面分辨率

我正在制作一个C++游戏,我想让它自动获得用户的桌面分辨率.

到目前为止,我找到了仅限Windows的解决方案 - 是否有方法/库可以在Windows/Mac/Linux上找到解决方案?

c++ portability gcc screen-resolution

10
推荐指数
3
解决办法
5187
查看次数

"模板模板参数的模板参数必须是类模板或类型别名模板"

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.

c++ templates clang variadic-templates c++11

10
推荐指数
1
解决办法
8724
查看次数

使用g ++ 6.1可能的std :: forward回归 - 错误或预期的行为?

g ++ 6.1最近被引入到Arch Linux的测试库中,我用g ++ 5.3.0成功编译的一些代码不再编译了.我做了一个最小的例子:

gcc.godbolt.org链接

// 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)

c++ lambda gcc perfect-forwarding c++14

10
推荐指数
1
解决办法
159
查看次数

C++ 17可以推导出具有显式非类型参数的`auto`非类型`模板`参数模式匹配模板吗?

考虑这个例子(也可以在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中找不到任何结论.

c++ templates auto c++17

10
推荐指数
1
解决办法
360
查看次数

将多个元组应用于同一个函数(即`apply(f,tuples ...)`)而不进行递归或`tuple_cat`

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 …

c++ templates tuples variadic-templates c++17

10
推荐指数
1
解决办法
565
查看次数

`nodcept`函数中的`std :: terminate`调用,可见性有限 - gcc vs clang codegen

请考虑以下代码段:

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)

godbolt.org上的实例


怎么g++逃避这个?不应该在调用方生成代码,因为主体f不可见? …

c++ code-generation exception noexcept c++11

10
推荐指数
1
解决办法
197
查看次数

为什么`polymorphic_allocator`需要`memory_resource`指针而不是引用?

C ++ 17标准说:

[mem.poly.allocator.ctor]

polymorphic_allocator(memory_resource* r);
Run Code Online (Sandbox Code Playgroud)
  • 要求: r非空。

  • 效果:设置memory_­rsrcr

  • 抛出:没事。

  • [?注意:此构造函数提供的隐式转换memory_­resource*。-?尾注?]

如果“ requires”子句提到必须为非null ,那么接受a memory_resource*而不是a memory_resource&的意义何在?r

彭博(Bloomberg¹)风格指南鼓励接受将要通过指针而不是引用进行突变的参数,以便调用方的“与”号成为可见的突变标记。但是,标准中没有此类先例。

r被视为指针而不是参考的原因是什么?


¹ pmr与重彭博参与规范,因为该公司采用的是多态的分配模式。

c++ allocator language-lawyer c++17

10
推荐指数
1
解决办法
232
查看次数