小编chr*_*ris的帖子

类的成员是否可以与其类型(另一个类)命名相同的名称?

尝试在不同的编译器上编译以下代码给我两个不同的结果:

struct S{};
struct T{S S;};
int main(){}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在内部T,我有一个与之前定义的类名称相同的对象S.


在GCC 4.7.2上,我收到S S;内部声明有关的以下错误T:

错误:声明'ST :: S'[-fpermissive]
错误:从'struct S'改变'S'的含义[-fpermissive]

但是,将它移到课堂外(或进入main)可以正常工作:

struct S{};
S S;
int main(){}
Run Code Online (Sandbox Code Playgroud)

它给我的错误究竟是什么意思?


在Visual Studio 2012中,整个事件编译并运行没有任何错误.将它粘贴到这个Clang 3.0编译器中也没有错误.

哪个是对的?我真的可以这样做吗?

c++ implementation g++ clang visual-c++-2012

9
推荐指数
3
解决办法
2801
查看次数

如何在CodeBlocks附加链接器选项中指定子系统?

我觉得CodeBlocks的一个好处是它允许我快速创建,编译和运行文件而无需创建项目.但是,这意味着我的所有程序都有控制台窗口,这对大多数Windows应用程序来说都是不正常的.

为了摆脱它,我总是不得不创建一个项目,抛出我的文件,然后导航到我可以单击GUI应用程序而不是控制台应用程序的位置.

但是,显然可以在使用g ++.exe和ld.exe构建时指定相同的东西,而CodeBlocks有一个部分用于其他链接器选项,所以我想我可以将其粘贴在那里以避免总是创建项目的麻烦,但显然我错了.

首先,我发现了这个问题.当我发现谁回答它时,我感到很惊讶,但这对我没有帮助,因为这一点的重点在于,我可以在创建项目的情况下以相同的努力来做到这一点.

显然,-mwindows编译器选项会这样做,所以我尝试将其放入Settings\Compiler and Debugger\Compiler settings\Other options,并且编译和链接很好,但仍然有一个控制台窗口.

接下来,我试过了Settings\Compiler and Debugger\Linker settings\Other linker options.在谷歌搜索结果的推动下,我尝试在其中添加以下内容,一次激活一个选项,然后重建.有-mwindows积极的没有什么区别,据我可以告诉.


-Wl :无法识别的命令行选项--subsystem,windows:无法识别的命令行选项
--subsystem,windows:windows - 没有这样的文件或目录.
--subsystem windows:windows - 没有这样的文件或目录.
--subsystem = windows:Unregocnized命令行选项
--subsystem,console:console - 没有这样的文件或目录.

此测试全部在最新版本的CodeBlocks,CodeBlocks 12.11和GCC 4.7.2上完成,从此MinGW发行版(版本9.4)获得.但是,我很确定它与CodeBlocks 10.05的工作方式相同.

我是否被迫使用项目,使用makefile或从命令行构建它,或者是否可以在CodeBlocks IDE全局设置中更改此设置?

c++ linker mingw options codeblocks

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

std :: is_constructible <void()> :: value的正确结果是什么?

我得到了不一致的结果std::is_constructible<void()>::value.我对标准的解释是它应该是假的.但是,使用libc ++和libstdc ++*的Clang都是真的.GCC和MSVC都给出了错误.哪个结果是正确的?

Standardese

这是标准,N4527 [meta.unary.prop]/7:

给出以下函数声明:

template <class T> add_rvalue_reference_t<T> create() noexcept;
Run Code Online (Sandbox Code Playgroud)

is_constructible<T, Args...>当且仅当以下变量定义适用于某些发明变量时,才应满足模板特化的谓词条件 t:

T t(create<Args>()...);
Run Code Online (Sandbox Code Playgroud)

注意:此文本与C++ 11(N3485)略有不同,后者create未标记noexcept.但是,考虑到这一点,我的测试结果没有改变.

测试用例

这是我的类型特征和标准定义的最小测试用例:

#include <type_traits>

static_assert(std::is_constructible<void()>::value, "assertion fired");

template<typename T>
std::add_rvalue_reference_t<T> create() noexcept;

template<typename T, typename... Args>
void foo() {
    T t(create<Args>()...);   
}

int main() {
    foo<void()>();   
}
Run Code Online (Sandbox Code Playgroud)

结果:

Clang(HEAD,libc ++):

  • 静态断言已通过
  • foo<void()> 没编译

Clang(HEAD,libstdc ++)*:

  • 静态断言已通过
  • foo<void()> 没编译

GCC(HEAD,libstdc ++):

  • 静态断言失败
  • foo<void()> 没编译

MSVC(版本19通过http://webcompiler.cloudapp.net/):

  • 静态断言失败
  • foo<void()> 没有编译(需要注释掉静态断言) …

c++ type-traits language-lawyer

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

当 x 的范围有限时,为什么 x/10 会通过不必要的偏移进行优化?

我有这个功能

long long int divideBy10(long long int a){
    return a / 10;
}
Run Code Online (Sandbox Code Playgroud)

它被编译为:

        mov     rax, rdi
        movabs  rcx, 7378697629483820647
        imul    rcx
        mov     rax, rdx
        shr     rax, 63
        sar     rdx, 2
        add     rax, rdx
        ret
Run Code Online (Sandbox Code Playgroud)

如果我添加 __builtin_assume(a > 0);

它被编译为

        mov     rax, rdi
        movabs  rcx, -3689348814741910323
        mul     rcx
        mov     rax, rdx
        shr     rax, 3
        ret
Run Code Online (Sandbox Code Playgroud)

代码效率更高,因为它不必担心负号。现在,如果我添加 __builtin_assume(a < 10000); 我原以为它会被编译成一个乘法而没有移位。但事实并非如此。

我想也许编译器只跟踪数字是正数还是负数,但是

long long int noBranch(long long int a){
    __builtin_assume(a < 400);
    if( a < 500){
        return a;
    }
    return 0; …
Run Code Online (Sandbox Code Playgroud)

c++ compiler-construction assembly compiler-optimization

9
推荐指数
0
解决办法
206
查看次数

我可以使用变量模板来声明另一个变量模板吗?

随着C++ 14中的变量模板(以及Clang已经支持它们)和标准is_same_v类型特征的提议,我认为能够制作新的类型特征如下:

template<typename T>
constexpr bool is_const_and_volatile{std::is_const_v<T> && std::is_volatile_v<T>};
Run Code Online (Sandbox Code Playgroud)

唉,这会导致错误等同于以下SSCCE(这个包含下面提到的所有内容):

#include <type_traits>

template<typename T>
constexpr bool is_pointer{std::is_pointer<T>::value};

template<typename T>
constexpr bool foo{is_pointer<T>};

int main() {
    //foo<int *>;
}
Run Code Online (Sandbox Code Playgroud)

main评论中,Clang吐出以下内容:

警告:变量is_pointer<type-parameter-0-0>具有内部链接但未定义

它看起来定义为我的(注意,更改Tint *foo正常工作).在取消注释行main实例foo给出了这样的(再次,Tint *优良工程):

错误:constexpr变量foo<int *>必须由常量表达式初始化

但是,foo使用以下旧语法替换会导致两个实例都正常工作:

constexpr bool foo{std::is_pointer<T>::value};
Run Code Online (Sandbox Code Playgroud)

关于变量模板有什么我想念的吗?有没有办法它们构建新的变量模板,或者我是否被迫使用旧的语法来构建新的模板,并且在将它们用于其他代码时只享受语法糖?

c++ variable-templates c++14

8
推荐指数
1
解决办法
398
查看次数

VLC如何在桌面上播放视频?

前段时间,我注意到VLC能够直接在桌面上播放视频.当我在学校这样做时,在Windows XP上,它在图标下方播放.当我在家里尝试时,在Windows 7上,它隐藏了图标.我不确定它是操作系统还是VLC的更新,但我有兴趣在图标下面播放它.

注意到这一点后,我有一个想法,制作各种动画桌面.没有什么特别的,只有几个选择视频供我自己使用.我开始的想法是在我自己的窗口中播放视频(使用mciSendString)并执行PrintWindow每个帧的一个,将其保存到文件,并将桌面壁纸设置为文件.我已经丢失了特定的代码,但它不是很有用,而且,不用说,它会表现得非常糟糕.

回过头来,我意识到必须有一种比这更有效的方式,但我无法理解那是什么.

我尝试(现在都在Windows 7中)将视频的父窗口设置为GetDesktopWindow,以最小化所有窗口,在播放视频的任务栏上留下一个新窗口,但是能够通过单击aero peek按钮或点击来查看桌面WIN + d.

然后我尝试使用桌面文件夹视图窗口的父窗口.结果是播放视频的相同尺寸的窗口,但这次无法访问桌面,也没有创建新窗口.这就像是在桌面的大部分桌面上播放,但是由于播放窗口尺寸较小,小工具超过顶部,右侧和底部区域仍然显示.

VLC在桌面上玩什么,看起来好像是动态壁纸?是不是很难让它在图标下面播放(如果你在Windows 7中添加小工具,我想)?该程序本身将在Windows XP上使用.我不确定DirectShow是否有任何可能有用的东西,但我愿意使用它,除了MCI之外的其他Windows API领域.如果它有所作为,我宁愿使用C++解决方案..NET也可以很好地工作,但可能需要一些额外的时间.

c++ winapi desktop vlc

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

为什么std :: function在签名中接受这个引用?

成员函数具有隐式this指针参数.为什么std::function接受这个签名,那么,S是一个简单的类?(完整样本)

std::function<void(S &)> func = &S::foo;
Run Code Online (Sandbox Code Playgroud)

调用它也有效,并区分对象:

S s1 = {5};
S s2 = {6};

func(s1); //prints 5
func(s2); //prints 6
Run Code Online (Sandbox Code Playgroud)

我通常期望它需要一个指针,它也可以工作:( 完整样本)

std::function<void(S * const)> func = &S::foo;

S s1 = {5};
S s2 = {6};

func(&s1); //prints 5
func(&s2); //prints 6
Run Code Online (Sandbox Code Playgroud)

当隐式this参数是指针时,当我将引用传递给成员函数时,为什么第一个工作正常?

c++ function this

7
推荐指数
2
解决办法
139
查看次数

rand改变值而不改变种子

参加以下计划:

#include <cstdlib>
using std::rand;

#include <iostream>
using std::cout;

int main()
{
    cout << rand() << ' ' << rand() << ' ' << rand() << '\n';
}
Run Code Online (Sandbox Code Playgroud)

由于rand只要种子不使用而产生相同的值srand,这应该产生三个相同的数字.
例如

567 567 567
Run Code Online (Sandbox Code Playgroud)

但是,当我运行这个程序时,它给了我三个不同的值.
例如

6334 18467 41
Run Code Online (Sandbox Code Playgroud)

当程序(编译并)再次运行时,会生成相同的三个数字.srand在我开始得到不同的结果之前,我不应该用它来改变种子rand吗?这只是我的编译器/实现试图帮我一个忙吗?

操作系统:Windows XP
编译器:GCC 4.6.2
库:MinGW

编辑:通过尝试使用srand,我发现这是种子1的结果(我猜是默认).

c++ random random-seed

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

如何强制不修改引用变量的任何部分?

在引用某些内容时,可以添加额外的const限定符,以便不能修改引用的变量,如下所示:

int *ptr;
int const * const &rptr = ptr;
//ptr can't be changed and *ptr can't be changed
Run Code Online (Sandbox Code Playgroud)

或者像这样,使用数组:

int arr[1];
int const (&rarr)[1] = arr;
//arr[0] can't be changed
Run Code Online (Sandbox Code Playgroud)

或者甚至像这样,使用指针数组:

int *ptrarr[1];
int * const (&rptrarr)[1] = ptrarr;
//ptrarr[0] cannot be changed, but *ptrarr[0] can be
Run Code Online (Sandbox Code Playgroud)

那么,为什么我不能将这些结合起来呢?

int *ptrarr[1];
int const * const (&why)[1] = ptrarr; //error
Run Code Online (Sandbox Code Playgroud)

尝试此操作时,Clang 3.5会产生以下错误,而GCC 4.8.1会产生类似的错误:

错误:对类型的引用const int *const [1]无法绑定到类型的左值int *[1]

保护被引用的指针数组的所有部分的正确方法是什么const

注意:这是一个人为的例子,但我希望这会导致对语言的了解,以后可能会有用.

c++ arrays pointers const reference

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

变量值自身变化

之前在编程时我一直很困惑,但这一点很重要。基本上我在一个 for 循环中设置值,并在接下来的迭代中更改为下一个的值。

for (int i = 0; i < 2; ++i)
{
    for (int j = 0; j < numWords[i]; ++j) //numWords [0] = 9, numWords [1] = 7
    {
        stb[i][j].word = const_cast<char*>(is (j + 1,1).c_str()); //is(int,length[opt]) converts int to string, c_str() returns const char *, but I need char *
        cout << is(j+1,1) << ' ' << stb[i][j].word << '\n';
    }
}

for (int i = 0; i < 2; ++i)
{
    for (int j = 0; j …
Run Code Online (Sandbox Code Playgroud)

c++ const-cast

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