在C++ 03中,表达式是rvalue或lvalue.
在C++ 11中,表达式可以是:
两类已成为五大类.
sizeof在给出三元表达时,我很难理解行为.
#define STRING "a string"
int main(int argc, char** argv)
{
int a = sizeof(argc > 1 ? STRING : "");
int b = sizeof(STRING);
int c = sizeof("");
printf("%d\n" "%d\n" "%d\n", a, b, c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在此示例中(使用gcc 4.4.3和4.7.2进行测试,编译时-std=c99),b为9(8个字符+隐式'\0'),c为1(隐式'\0').a,出于某种原因,是4.
根据argc是否大于1,我希望a为9或1.我想也许字符串文字在被传递到之前转换为指针sizeof,导致sizeof(char*)为4.
我尝试替换STRING和""char数组...
char x[] = "";
char y[] = "a string";
int a = sizeof(argc > 1 ? x : y);
Run Code Online (Sandbox Code Playgroud)
...但我得到了相同的结果(a = …
我正在使用C++ 14中的constexpr函数进行实验.以下代码计算析因是按预期工作的:
template <typename T>
constexpr auto fact(T a) {
if(a==1)
return 1;
return a*fact(a-1);
}
int main(void) {
static_assert(fact(3)==6, "fact doesn't work");
}
Run Code Online (Sandbox Code Playgroud)
用clang编译如下:
> clang++ --version
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
> clang++ -std=c++14 constexpr.cpp
Run Code Online (Sandbox Code Playgroud)
但是,当我更改fact定义以使用三元?运算符时:
template <typename T>
constexpr auto fact(T a) {
return a==1 ? 1 : a*fact(a-1);
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译器错误:
> clang++ -std=c++14 constexpr.cpp
constexpr.cpp:12:31: fatal error: recursive template instantiation exceeded maximum depth of
256
return a==T(1) ? …Run Code Online (Sandbox Code Playgroud) 我很困惑这个:
#include <iostream>
struct X {};
void f( const X &x ) { std::cerr << &x << "\n"; }
static X x;
int main()
{
f( x ); // Off stack address
f( false ? X() : x ); // Different address on stack.
}
Run Code Online (Sandbox Code Playgroud)
为什么f的第二次调用会产生临时副本?
编辑:这个问题不是关于类型X,而是复制的事实.我从接受的答案中忽略了值类别的过剩,并且期望f的参数直接绑定在x或X()上,就像将其重新表述为if语句一样.
我有一个关于C++模板的问题.以下代码段错误.
template <typename T1, typename T2>
inline T1 const& max(T1 const &a, T2 const &b) {
return a < b ? b : a;
}
int main() {
std::cout << max(4.9, 4) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但是,删除&它会做正确的事情.
template<typename T1, typename T2>
inline T1 const max(T1 const &a, T2 const &b) {
return a < b ? b : a;
}
int main() {
std::cout << max(4.9, 4) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
此外,只需使用T代替T1和T2,它就可以正常工作.
template<typename T>
inline T const& max(T const &a, T const …Run Code Online (Sandbox Code Playgroud) #include <iostream>
#include <time.h>
class A
{
public:
A() { std::cout << "a ctor\n"; }
A(const A&) { std::cout << "a copy ctor\n"; }
A(A&&) { std::cout << "a move ctor\n"; }
};
A f(int i)
{
A a1;
return i != 0 ? a1 : A{};
}
int main()
{
srand(time(0));
f(rand());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
演员
复印机
我预计A1在F()将被移动不会被复制。如果我稍微改变f(),它就不再是一个副本而是一个移动:
A f(int i)
{
A a1;
if (i != 0)
{
return a1;
} …Run Code Online (Sandbox Code Playgroud) int使用 Clang 和unsigned intGCC为 x86_64 编译时会打印以下代码。
我不确定哪个(如果有的话)是正确的。
#include <stdio.h>
struct s {
unsigned int x : 1;
};
template<typename T>
void f(T) {}
template<> void f<int>(int) {
printf("int\n");
}
template<> void f<unsigned int>(unsigned int) {
printf("unsigned int\n");
}
struct s r;
int main()
{
f(0 ? r.x : 0);
}
Run Code Online (Sandbox Code Playgroud)
如果我们用(r.x + 0)两个编译器替换条件,就说类型是有符号的。
C++ 标准部分 expr.cond 有许多转换规则,但似乎没有一个案例涵盖不同类型的泛左值和纯右值之间的转换问题。
是否将无符号位域提升为有符号整数是否由实现定义?
最小的代码重现问题:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
CComBSTR ccbTest( L"foo" );
const wchar_t * pTest = ccbTest ? ccbTest : L"null string";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器CComBSTR在想要存储指针时使用临时pTest.然后它使用类中BSTR可用的转换CCcomBSTR,使用临时,并将指针存储在其中pTest.然后临时被摧毁,我留下一个悬垂的指针pTest.
解决方法是施放CComBSTR:
const wchar_t * pTest = ccbTest ? static_cast<BSTR>( ccbTest ) : L"null string";
Run Code Online (Sandbox Code Playgroud)
我不明白为什么修复是必要的.我认为编译器只会尝试自己转换为BSTRall.为何暂时?
我有一个重载函数,可以采用两种参数类型:int和double.当我使用可以返回a int或a 的三元进行评估时double,它总是使用该double版本.这是为什么?
#include<iostream>
using namespace std;
void f(int a)
{
cout << "int" << endl;
}
void f(double a)
{
cout << "double" << endl;
}
int main()
{
string a;
cin >> a;
f(a=="int" ? 3 : 3.14159);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我对这里发生的事情有一个模糊的想法......它与此有关,但我想知道为什么clang ++和g ++处理这个问题的方式不同.这里的未定义行为在哪里?注意:这与模板无关 - 我只是使用它们来使示例更紧凑.这都是关于它的类型whatever.
#include <iostream>
#include <vector>
template <typename T>
void test()
{
T whatever = 'c';
const char a = 'a';
std::cout << "begin: " << (void*)&a << std::endl;
const char & me = (true ? a : whatever);
std::cout << "ref: " << (void*)&me << std::endl;
}
int main(int argc, char**argv)
{
test<const char>();
test<char>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc输出(测试高达4.9.3):
begin: 0x7fffe504201f
ref: 0x7fffe504201f
begin: 0x7fffe504201e
ref: 0x7fffe504201f
Run Code Online (Sandbox Code Playgroud)
clang 3.7.0输出:
begin: 0x7ffed7b6bb97
ref: …Run Code Online (Sandbox Code Playgroud)