小编Inn*_*der的帖子

std :: function的仅移动版本

因为std::function是可复制的,所以标准要求用于构造它的callables也是可复制的:

n337(20.8.11.2.1)

template<class F> function(F f);

要求:F应为CopyConstructible.f对于参数类型ArgTypes和返回类型,应为Callable(20.8.11.2)R.A的拷贝构造函数和析构函数不会抛出异常

这意味着不可能std::function从不可复制的绑定对象或捕获仅移动类型的lambda形成std::unique_ptr.

似乎可以为仅移动的callables实现这样一个仅移动的包装器.是否存在标准库仅限移动等效std::function或者,是否存在针对此问题的常见解决方法?

c++ move-semantics c++11

51
推荐指数
3
解决办法
6242
查看次数

g ++ rejects,clang ++接受:foo(x)("bar")("baz");

前几天有人曾过为什么有些东西会与clang编译,而不是与gcc编译.我直观地理解了发生了什么,并且能够帮助这个人,但它让我想知道 - 根据标准,哪个编译器是正确的?这是代码的简化版本:

#include <iostream>
#include <string>

class foo
{
public:
    foo(const std::string& x):
        name(x)
    { }
    foo& operator()(const std::string& x)
    {
        std::cout << name << ": " << x << std::endl;
        return (*this);
    }
    std::string name;
};

int main()
{
    std::string x = "foo";
    foo(x)("bar")("baz");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用clang ++可以很好地编译,但是g ++会出现以下错误:

runme.cpp: In function ‘int main()’:
runme.cpp:21:11: error: conflicting declaration ‘foo x’
    foo(x)("bar")("baz");
        ^
runme.cpp:20:17: error: ‘x’ has a previous declaration as ‘std::string x’
    std::string x = …
Run Code Online (Sandbox Code Playgroud)

c++ syntax g++ most-vexing-parse clang++

25
推荐指数
2
解决办法
514
查看次数

将文字作为const ref参数传递

想象一下以下简化代码:

#include <iostream>
void foo(const int& x) { do_something_with(x); }

int main() { foo(42); return 0; }
Run Code Online (Sandbox Code Playgroud)

(1)除了优化之外,42传递给什么时会发生什么foo

编译器是否在某处(在堆栈上?)并将其地址传递给foo

(1a)标准中是否有任何内容规定在这种情况下要做什么(或者它是否严格取决于编译器)?


现在,想象一下略有不同的代码

#include <iostream>
void foo(const int& x) { do_something_with(x); }

struct bar { static constexpr int baz = 42; };

int main() { foo(bar::baz); return 0; }
Run Code Online (Sandbox Code Playgroud)

它不会链接,除非我定义int bar::baz;(由于ODR?).

(2)除了ODR之外,为什么编译器不能对上面的42做什么呢?


简化事物的一种明显方法是定义foo为:

void foo(int x) { do_something_with(x); }
Run Code Online (Sandbox Code Playgroud)

但是,如果是模板,会怎么做?例如:

template<typename T>
void foo(T&& x) { do_something_with(std::forward<T>(x)); }
Run Code Online (Sandbox Code Playgroud)

(3)是否有一种优雅的方式来foo表示接受x原始类型的价值?或者我是否需要专注于SFINAE或其他一些?

编辑 …

c++ one-definition-rule c++11 pass-by-const-reference forwarding-reference

16
推荐指数
1
解决办法
1048
查看次数

在C++中使用enum而不是struct进行标签分派

让我们std::unique_lock从标准库中实现:

struct defer_lock_t { explicit defer_lock_t() = default; };
struct try_to_lock_t { explicit try_to_lock_t() = default; };
struct adopt_lock_t { explicit adopt_lock_t() = default; };

inline constexpr defer_lock_t  defer_lock {};
inline constexpr try_to_lock_t try_to_lock {};
inline constexpr adopt_lock_t  adopt_lock {};

unique_lock (mutex_type& m, defer_lock_t t) noexcept;
unique_lock (mutex_type& m, try_to_lock_t t);
unique_lock (mutex_type& m, adopt_lock_t t);
Run Code Online (Sandbox Code Playgroud)

是否有人不会/不能/不应该使用枚举而不是结构来实现标签调度?如:

enum defer_lock_t { defer_lock };
enum try_to_lock_t { try_to_lock };
enum adopt_lock_t { adopt_lock };

unique_lock (mutex_type& m, defer_lock_t t) noexcept; …
Run Code Online (Sandbox Code Playgroud)

c++ c++17 tag-dispatching

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

强制转换为enum不能表示的枚举值是否合法?

特定 enum class val { foo = 1, bar = 2, baz = 4 };

可以定义:

val operator|(val x, val y)
{
    return static_cast<val>(static_cast<int>(x) | static_cast<int>(y));
}
Run Code Online (Sandbox Code Playgroud)

但是,这样做在语义上是否正确?

我倾向于,如下所示,看似表现良好的例子:

int convert(val x)
{
    switch(x)
    {
    case val::foo: return 42;
    case val::bar: return 53;
    case val::baz: return 64;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用g ++和clang ++编译时,调用convert(val::foo | val::bar)将返回0.

是g ++版本.而这里是铛++版本.

我的问题是双重的:

  1. 将值存储在枚举器未表示的枚举中是否在语义上正确?我们非常欢迎该标准的摘录.

1.a在上面链接的例子中,哪个编译器是正确的,g ++或clang ++?

  1. 是否有标准(或建议)的方式来表示C++中的标志?

我可以想到几种可能的实现:

enum class val { foo, bar, baz, size …
Run Code Online (Sandbox Code Playgroud)

c++ enums c++11

9
推荐指数
1
解决办法
741
查看次数

使用throw dtor和libc ++的std :: make_shared无法编译

这是非常基本的代码:

#include <memory>

class foo
{
public:
    ~foo() noexcept(false) { }
};

int main()
{
    auto x = std::make_shared<foo>();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译如下:

g++ -std=c++11 test.cpp          <-- OK
clang++ -std=c++11 test.cpp          <-- OK
clang++ -std=c++11 -stdlib=libc++ test.cpp          <-- FAIL
Run Code Online (Sandbox Code Playgroud)

使用libc ++编译时,它会失败:

/usr/bin/../include/c++/v1/memory:3793:7: error: exception specification of overriding function is more lax than base version
class __shared_ptr_emplace
    ^
/usr/bin/../include/c++/v1/memory:4423:26: note: in instantiation of template class 'std::__1::__shared_ptr_emplace<foo,
    std::__1::allocator<foo> >' requested here
    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
                        ^
/usr/bin/../include/c++/v1/memory:4787:29: note: in instantiation of function template …
Run Code Online (Sandbox Code Playgroud)

c++ g++ c++11 clang++ libc++

9
推荐指数
1
解决办法
321
查看次数

我们在c ++ 17中有自动数组吗?

auto numbers = {1, 2, 3, 4};    // 'numbers' is an std::intializer_list<int>
auto num_array[] = {1, 2, 3, 4} // error -> declared as an array of 'auto'
Run Code Online (Sandbox Code Playgroud)

为什么会出现这种限制?

c++ c++17

9
推荐指数
2
解决办法
839
查看次数

范围结束时的左值是否可以视为右值?

编辑:考虑以下两个例子:

std::string x;
{
    std::string y = "extremely long text ...";
    ...
    x = y; // *** (1)
}
do_something_with(x);
Run Code Online (Sandbox Code Playgroud)
struct Y
{
    Y();
    Y(const Y&);
    Y(Y&&);
    ... // many "heavy" members
};

struct X
{
    X(Y y) : y_(std::move(y)) { }
    Y y_;
}

X foo()
{
    Y y;
    ...
    return y; // *** (2)
}
Run Code Online (Sandbox Code Playgroud)

y在线(1)和(2)的两个例子中,它的寿命接近结束并且即将被破坏.很明显,它可以被视为右值并在两种情况下都可以移动.在(1)中,它的内容可以移入x和移入(2)到temp的实例中X().y_.

我的问题是:

1)是否会在上述任何一个示例中移动?(a)如果是,则采用何种标准规定.(b)如果不是,为什么不呢?这是标准中的遗漏还是我没有想到的另一个原因?

2)如果上述答案为否.在第一个例子中,我可以改变(1)x = std::move(y)以强制编译器执行移动.在第二个示例中,我可以做什么来向编译器指示y可以移动?return std::move(y)

注意:我故意返回(2)中的实例Y而不是X …

c++ lvalue-to-rvalue c++14

6
推荐指数
1
解决办法
237
查看次数

使用带有std :: optional参数的std :: function重载歧义

这是一个简单的示例程序:

using fn_string = function<void(const string&)>;
using fn_optional_string = function<void(const optional<string>&)>;

void foo(fn_string) { cout << "string" << endl; }
void foo(fn_optional_string) { cout << "optional string" << endl; }

int main()
{
    foo([&](const string&){ });
    foo([&](const optional<string>&){ }); // <-- ambiguous
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它有2个重载foo()- 一个带string参数函数,另一个带函数optional<string>.

为什么第二次呼叫foo()模棱两可?

有没有一种简单的方法来解决它?没有演员阵容?

UPDATE

以上是我试图解决的以下现实世界问题的过度简化示例,即:

using delegate = variant<
    function<void()>,
    function<void(const string&)>,
    function<void(const optional<string>&)>
>;

struct foo
{
    void add_delegate(delegate fn) { fns.push_back(std::move(fn)); }
    vector<delegate> fns; …
Run Code Online (Sandbox Code Playgroud)

c++ c++17

6
推荐指数
1
解决办法
262
查看次数

如何在 D3D 窗口应用程序中启用 VSYNC?

因此,我在窗口应用程序中使用 D3D。

我使用以下参数启动了 D3D:

windowed: true;
backbufferformat: D3DFMT_X8R8G8B8;
presentinterval: D3DPRESENT_INTERVAL_ONE;
swapeffect: DISCARD
Run Code Online (Sandbox Code Playgroud)

每次调用 OnPaint 时,我都会将图像渲染到后缓冲区并将其呈现到前面。

据我所知(MSDN也是这么说的),一旦我设置了D3DPRESENT_INTERVAL_ONE,vsync就会起作用。

但在这种情况下,水平拖动时图像会撕裂。

(图像上似乎有一条线,线下方的图像显示在监视器上,上面的部分如下。)

一些网站说 D3DPRESENT_INTERVAL_ONE 在窗口应用程序中不起作用。

我怎样才能启用垂直同步?

ps我终于发现D3D垂直同步是启用的,而有些窗口设置不正确,也许窗口本身没有同步。不过,我还没有看过设置。

directx direct3d vsync direct3d9

5
推荐指数
2
解决办法
2万
查看次数