小编NKa*_*tUT的帖子

根据可调用的签名自动选择一元与二进制 std::transform 函数重载

std::transform提供采用一元(一个参数)或二元(两个参数)可调用操作(通常为 lambda)的重载。

我想将我想要的可调用对象作为参数传递给父函数,并使用编译时(例如模板元编程)方法std::transform根据传递的可调用对象是否具有带有一个的函数签名来自动选择使用哪个重载或两个论点。

这是用(尚未工作)代码表达的所需方法:

#include <algorithm>

auto UnaryOp = [](const auto& src) { return src; };                                 // simple copy
auto BinaryOp = [](const auto& src1, const auto& src2) {return src1 + src2; };      // accumulate

auto GenericTransformer = [](auto src, auto dst, auto operation) {  // operation is unary OR binary

    /* unrelated code */

        // need to chose this one:
    std::transform(src.begin(), src.end(), dst.begin(), operation);
        // or this one:
    std::transform(src.begin(), src.end(), dst.begin(), dst.begin(), operation);
        // depending on …
Run Code Online (Sandbox Code Playgroud)

c++ lambda dry compile-time template-meta-programming

7
推荐指数
1
解决办法
101
查看次数

为什么带有 decltype 参数的方法的显式实例化在 GCC/Clang 中有效,但在 MSVC 中无效

以下程序使用自动参数生成函数模板,然后显式实例化它们,将在 g++ 和 clang (x86-64 trunk, -std=c++20) 中正常编译,但在 MSVC (x64 v19.latest) 中给出错误 C2945 和 C3190 /std:c++20)。

https://godbolt.org/z/xsWcezzz6

#include <cstdint>
#include <concepts>

template <typename T>
concept MyType = std::same_as<T,uint16_t> || std::same_as<T,uint32_t>;

class A {
public:
    void Foo(uint32_t arg1, MyType auto arg2);
    void Bar(uint32_t agr1, MyType auto arg2, decltype(arg2) arg3);
};

void A::Foo(uint32_t arg1, MyType auto arg2) {}         // define
template void A::Foo(uint32_t, uint16_t);               // explicit instantiate for uint16_t
template void A::Foo(uint32_t, uint32_t);               // explicit instantiate for uint32_t

void A::Bar(uint32_t arg1, MyType …
Run Code Online (Sandbox Code Playgroud)

c++ templates decltype

6
推荐指数
0
解决办法
129
查看次数

为什么不允许 constexpr 局部变量作为默认函数参数?

我想我明白为什么 C++ 不允许局部变量作为默认函数参数:

int main () {
   auto local{1024};
   auto lambda = [](auto arg1 = local){};    // "illegal use of local variable as default parameter"
}
Run Code Online (Sandbox Code Playgroud)

但即使该变量是constexpr local也是不允许的:

int main () {
   constexpr auto local{1024};
   auto lambda = [](auto arg1 = local){};    // "illegal use of local variable as default parameter"
}
Run Code Online (Sandbox Code Playgroud)

但是,允许使用全局变量(即使是非 constexpr):

int global;
int main () {
   auto lambda = [](int arg1 = global){};    // OK
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释在这种情况下不允许使用 constexpr 局部变量的理由吗?当默认值是固定的并且在编译时已知时,编译器似乎应该能够为函数构造适当的“默认参数”重载。

c++ default-arguments constexpr

4
推荐指数
1
解决办法
69
查看次数

glClear()不服从剪刀区域

我正在使用双缓冲在任意已打开的Windows 7窗口(例如Windows记事本窗口)中绘制Open GL内容(直接Win32 - 不使用GLUT,FreeGLUT,GLFW等).我有窗口句柄,可以按预期绘制我想要的内容,但我看到该glClear()功能的奇怪行为.

我的理解是,该glClear()功能应该只影响屏幕上由glScissor()功能定义的区域内的像素.我已经定义了剪刀区域,glScissor()然后启用了剪刀功能glEnable(GL_SCISSOR_TEST).glClearColor设置为白色(0,0,0,1).我正在用glClear()命令清除颜色和深度缓冲区.

SwapBuffers()命令以呈现在屏幕上被执行时,我选择了白色的清澈颜色被涂成剪刀区域内,因为我的要求,但窗口的其余部分OUTSIDE剪刀区域被涂成黑色,而不是把这些像素不变的我期望.

正如图中所示,剪刀区域(白色)和对象(3D立方体)的正确绘制,但记事本窗口的像素的其余部分设置为黑色,以前在记事本窗口中画任何东西覆盖了.

glClearColor(1.0f, 1.0f, 1.0f, 1.0f);               // white background
glViewport(0, 0, 300, 300);
glScissor(0, 0, 250, 400);
glEnable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//... draw cube inside glBegin()/glEnd()...
SwapBuffers(hDC);
Run Code Online (Sandbox Code Playgroud)

c++ windows opengl

2
推荐指数
1
解决办法
943
查看次数

是否有一种 STL 算法或 C++ 习惯用法可以根据谓词将一项从一个 std::list 移动到另一个?

我有一个工作流程,其中我从可移动对象的 std::list 开始,我想遍历此列表,将满足特定条件(即一元谓词返回 true)的元素移动到不同的 std::list (例如使用back_inserter 到现有列表,甚至构建一个新列表)。

我考虑过std::list::remove_if,但如果满足条件,它只会破坏元素,并返回删除的元素总数 - 但这些元素将永远丢失。

我还考虑过std::remove_copy_if,但是如果不满足条件,则复制元素并将元素保留在原始列表中。

我的希望/假设是,基于谓词将一个列表一分为二将是一种常见的用例,以至于 std::list 将有一个成员函数来将其作为单行执行,或者可以使用 STL 算法通过迭代器来做到这一点...但我没有找到任何东西。我是否遗漏了一些明显的东西,或者这只是尚未在 STL 中实现?

我希望解决方案的伪代码类似于这个人为的“move_if”std::list 成员函数:

std::list<T> source{ /* some objects of type T */ };
std::list<T> removed{};
source.move_if(std::back_inserter(removed), [&](const auto& e){ /* test e and return a bool */ });
Run Code Online (Sandbox Code Playgroud)

或者这个为删除的元素构造并返回一个新列表:

std::list<T> removed = source.move_if([&](const auto& e){ /* test e and return a bool */ });
Run Code Online (Sandbox Code Playgroud)

如果STL中还没有固定的解决方案,那么是否有一个首选的习惯用法来“手动”执行此操作(例如在原始循环中),编译器最有可能能够相对于其他手动方法进行优化?此外,是否有技术原因导致这还不是受支持的库函数,或者我是否夸大了它对其他人的有用性?谢谢!

c++ algorithm predicate move stdlist

2
推荐指数
1
解决办法
208
查看次数