尝试在不同的编译器上编译以下代码给我两个不同的结果:
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编译器中也没有错误.
哪个是对的?我真的可以这样做吗?
我觉得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全局设置中更改此设置?
我得到了不一致的结果std::is_constructible<void()>::value.我对标准的解释是它应该是假的.但是,使用libc ++和libstdc ++*的Clang都是真的.GCC和MSVC都给出了错误.哪个结果是正确的?
这是标准,N4527 [meta.unary.prop]/7:
给出以下函数声明:
Run Code Online (Sandbox Code Playgroud)template <class T> add_rvalue_reference_t<T> create() noexcept;
is_constructible<T, Args...>当且仅当以下变量定义适用于某些发明变量时,才应满足模板特化的谓词条件t:Run Code Online (Sandbox Code Playgroud)T t(create<Args>()...);
注意:此文本与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)
foo<void()> 没编译foo<void()> 没编译foo<void()> 没编译MSVC(版本19通过http://webcompiler.cloudapp.net/):
foo<void()> 没有编译(需要注释掉静态断言) …我有这个功能
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++ 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>具有内部链接但未定义
它看起来定义为我的(注意,更改T到int *在foo正常工作).在取消注释行main实例foo给出了这样的(再次,T以int *优良工程):
错误:constexpr变量
foo<int *>必须由常量表达式初始化
但是,foo使用以下旧语法替换会导致两个实例都正常工作:
constexpr bool foo{std::is_pointer<T>::value};
Run Code Online (Sandbox Code Playgroud)
关于变量模板有什么我想念的吗?有没有办法用它们构建新的变量模板,或者我是否被迫使用旧的语法来构建新的模板,并且在将它们用于其他代码时只享受语法糖?
前段时间,我注意到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也可以很好地工作,但可能需要一些额外的时间.
成员函数具有隐式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参数是指针时,当我将引用传递给成员函数时,为什么第一个工作正常?
参加以下计划:
#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的结果(我猜是默认).
在引用某些内容时,可以添加额外的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?
注意:这是一个人为的例子,但我希望这会导致对语言的了解,以后可能会有用.
之前在编程时我一直很困惑,但这一点很重要。基本上我在一个 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)