小编Dun*_*can的帖子

Visual Studio 2013中的默认移动构造函数(更新3)

我过去能够找到关于此的多个对话(例如这里),但这种对话来自不久前.我有一个问题的代码是:

#include <utility>
#include <iostream>

struct Foo
{
    Foo() = default;
    Foo(const Foo &o)
    {
        std::cout << "copy" << std::endl;
    }
    Foo(Foo &&o)
    {
        std::cout << "move" << std::endl;
    }
};

struct Bar
{
    Foo foo;
};

int main(void)
{
    Bar a;
    Bar b(a);
    Bar c(std::move(a));
}
Run Code Online (Sandbox Code Playgroud)

如果在Visual Studio 2013(Update 3)中执行代码,则会为两种情况打印出"copy".如果标准自上面的链接中的答案以来没有改变,那么输出应该是"复制",然后是"移动".Ideone似乎给出了正确的输出.这只是Visual Studio尚未实现的东西,还是我的代码中缺少某些东西?我知道你不能将构造函数标记为默认值,但这并不意味着编译器不支持一起生成默认移动构造函数.

c++ c++11

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

SetStdHandle对cout/printf没有影响

标题说明了一切.当我运行以下代码时:

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hFile = CreateFile(TEXT("Foo.txt"), GENERIC_WRITE, FILE_READ_ACCESS | FILE_WRITE_ACCESS,
    NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

SetStdHandle(STD_OUTPUT_HANDLE, hFile);
std::cout << "Hello, ";
printf("world!\n");
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello, world!\n", 13, NULL, NULL);

SetStdHandle(STD_OUTPUT_HANDLE, hOut);
CloseHandle(hFile);
Run Code Online (Sandbox Code Playgroud)

其结果是,Hello, world!被写入到控制台呼叫的一个结果coutprintf,和Hello, world!也被写入文件Foo.txt的调用的结果WriteFile.我的假设是,当一切都在一开始就被初始化时,HANDLE返回的GetStdHandle被缓存并重用于coutprintf.这是完全合理的,正如我所想的那样,我GetStdHandle需要调用操作系统(可能很长!).麻烦的是我想要覆盖这种行为并尽可能地将cout和printf与应用程序的标准句柄"同步".

在建议任何替代方案之前,让我准确描述一下我正在尝试做什么(是的,我知道可以freopen用于此目的).我需要做的是在更改之前将当前标准输出句柄"保存"在类似堆栈的数据结构上,以便我能够恢复以前的输出句柄.任何不足之处都是这种情况所不能接受的(即我无法恢复CONOUT$等).这需要具有递归的能力.即以下应该按照您的预期工作:

std::cout << "A1" << std::endl;

StartStdOutRedirection(TEXT("Foo.txt"));
std::cout << "B1" << std::endl;

StartStdOutRedirection(TEXT("Bar.txt"));
std::cout << "C1" << std::endl; …
Run Code Online (Sandbox Code Playgroud)

windows winapi visual-c++

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

加载/存储到XMFLOAT4比使用XMVECTOR更快?

我经历了DirectX数学/ XNA数学库,和我好奇,当我读到有关对齐要求XMVECTOR(现在DirectX::XMVECTOR),以及它是如何对你的期望使用XMFLOAT*会员相反,使用XMLoad*XMStore*执行数学运算时.我特别好奇这个权衡,所以我做了一个实验,因为我相信很多其他人都有,并且经过测试,确切地知道你为每次操作加载和存储向量的确有多少.这是结果代码:

#include <Windows.h>

#include <chrono>
#include <cstdint>
#include <DirectXMath.h>
#include <iostream>

using std::chrono::high_resolution_clock;

#define TEST_COUNT          1000000000l

int main(void)
{
    DirectX::XMVECTOR v1 = DirectX::XMVectorSet(1, 2, 3, 4);
    DirectX::XMVECTOR v2 = DirectX::XMVectorSet(2, 3, 4, 5);
    DirectX::XMFLOAT4 x{ 1, 2, 3, 4 };
    DirectX::XMFLOAT4 y{ 2, 3, 4, 5 };

    std::chrono::system_clock::time_point start, end;
    std::chrono::milliseconds duration;

    // Test with just the XMVECTOR
    start = high_resolution_clock::now();
    for (uint64_t i = 0; i < TEST_COUNT; …
Run Code Online (Sandbox Code Playgroud)

directx direct3d directx-11

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

在VC++中获取子进程的环境变量

好的,这基本上就是我想要做的.我有一个过程P1.此过程需要cl.exe在单独的进程中调用Visual Studio命令行编译器P2(显然).但是,正如使用Visual Studio命令行编译器的每个人都知道的那样,您不能简单地调用cl.exe并期望获得良好的体验.您必须首先运行批处理脚本%VSXXXCOMNTOOLS%\vsvars32.bat(XXXVisual Studio版本号在哪里).此脚本设置编译器使用的一些关键环境变量(例如用作包含路径的内容).使用批处理脚本,这非常容易:

call "%VS110COMNTOOLS%\vsvars32.bat"
...
cl Foo.cpp Bar.cpp ...
Run Code Online (Sandbox Code Playgroud)

因为只是从批处理脚本调用批处理文件在同一个进程中运行(因此添加的环境变量是持久的).在我意识到我需要更多的灵活性并决定将我的脚本移植到C++之前,这是我过去常常做的事情,到目前为止,C++运行得非常好.也就是说,直到我达到我需要实现实际编译的程度.

所以,这是我最终要解决的问题.我想出最好的办法是调用cmd.exe /c "%VS110COMNTOOLS%\vsvars32.bat"一个单独的进程P3使用CreateProcess,等待进程结束,然后提取该子进程修改后的环境变量.也就是说,P1创建P3并等待它完成.P1然后将P3环境变量设置为自己的环境变量.P1然后创建P2这些环境变量集.所以代码大致如下(减去所有错误检查):

...
CreateProcess(TEXT("cmd"), TEXT("/c \"%VS110COMNTOOLS%\vsvars32.bat\""), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);

WaitForSingleObject(pi.hProcess, INFINITE);

/* Set current process environment using pi.hProcess */
CloseHandle(pi.hProcess);

...

CreateProcess(TEXT("cl"), TEXT("..."), NULL, NULL, FALSE, 0, NULL, NULL, &si, …
Run Code Online (Sandbox Code Playgroud)

windows winapi visual-c++

5
推荐指数
1
解决办法
1088
查看次数

当没有任何意义时,如何使用“Iterator::pointer”?

例如,考虑一些to_upper_iterator迭代一系列字符的假设,std::toupper返回operator*。这些迭代器别名对我来说很有意义:

template <typename CharT>
struct to_upper_iterator
{
    using value_type = CharT;
    using reference = CharT;
    using difference_type = std::ptrdiff_t;
    using iterator_category = std::random_access_iterator_tag;
};
Run Code Online (Sandbox Code Playgroud)

没有意义的是别名应该/可以使用什么pointer。我尝试将其关闭,但果然出现了编译错误。这似乎是由于 C++17 中的添加所致。en.cppreference.com总结的类型std::iterator_traits

如果Iterator不具有五种成员类型difference_typevalue_typepointerreferenceiterator_category,则此模板没有任何这些名称的成员(std::iterator_traits对 SFINAE 友好)

所以问题是:对于这样的类型,我应该只定义pointer一些东西- 我最喜欢的东西是voidvoid*- 或者做一些像专门化这样的事情更有意义,std::iterator_traits<to_upper_iterator>这样它就不包含pointer.

c++

5
推荐指数
1
解决办法
582
查看次数

关于C++全局命名空间的困惑

根据我的理解,追加::到命名空间的前面是指全局命名空间,而不管任何using语句或父命名空间.如果是这种情况,并且我没有误解任何内容,那么为什么这样的代码会编译(至少在Visual Studio中):

namespace Foo {
    namespace Bar {
        class X;
    }
}

using namespace Foo;
int main(void)
{
    ::Bar::X x;
}
Run Code Online (Sandbox Code Playgroud)

c++ scope namespaces

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

什么时候指向数组的指针可以转换为不同类型的指针数组?

我正在查看cppreference文档,std::unique_ptr并注意到C++ 17似乎已经做了一些有趣的更改.特别是,std::unique_ptr<T[]>现在的特化接受模板参数,它之前只接受std::unique_ptr::pointer参数.例如,以下是其中一个reset成员函数的声明std::unique_ptr<T[]>:

template <typename U> void reset(U p);
Run Code Online (Sandbox Code Playgroud)

该网站声明:

行为一样的reset主模板的成员,但它只会参与重载分辨率如果任 U是相同的类型pointer,或者 pointer是相同的类型element_type*U是指针类型V*,使得V(*)[]可转换为element_type(*)[].

我假设这是为了安全 - 你不想delete[]在指向指向其基类型指针的派生类型数组的指针上执行(在C++ 17之前,这被标记为已删除) .正如所料,此代码编译良好:

#include <type_traits>

struct foo {};
struct bar : public foo {};
static_assert(!std::is_convertible_v<bar(*)[], foo(*)[]>);
Run Code Online (Sandbox Code Playgroud)

然而,有趣的是,以下内容无法编译,两者都失败static_assert:

#include <type_traits>

struct foo {};
struct bar : public foo {};
static_assert(std::is_convertible_v<bar*(*)[], foo*(*)[]>);
static_assert(std::is_convertible_v<std::unique_ptr<bar>(*)[], std::unique_ptr<foo>(*)[]>); …
Run Code Online (Sandbox Code Playgroud)

c++ c++17

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

标签 统计

c++ ×4

visual-c++ ×2

winapi ×2

windows ×2

c++11 ×1

c++17 ×1

direct3d ×1

directx ×1

directx-11 ×1

namespaces ×1

scope ×1