相关疑难解决方法(0)

什么是右值,左值,x值,glvalues和prvalues?

在C++ 03中,表达式是rvaluelvalue.

在C++ 11中,表达式可以是:

  1. 右值
  2. 左值
  3. x值
  4. glvalue
  5. prvalue

两类已成为五大类.

  • 这些新的表达类别是什么?
  • 这些新类别如何与现有的左值和左值类别相关联?
  • C++ 0x中的右值和左值类别是否与它们在C++ 03中的相同?
  • 为什么需要这些新类别?是WG21神只是想迷惑我们凡人?

c++ expression c++-faq c++11

1291
推荐指数
13
解决办法
17万
查看次数

具有条件(三元)表达式的运算符'sizeof'

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 sizeof conditional-operator

13
推荐指数
2
解决办法
1103
查看次数

C++ 14:使用三元表达式从constexpr中推导出(自动)返回类型

我正在使用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)

c++ ternary-operator constexpr c++14

13
推荐指数
1
解决办法
1255
查看次数

为什么绑定到三元组的const引用会复制?

我很困惑这个:

#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++

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

c ++模板中的段错误

我有一个关于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)

c++ templates

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

为什么以下代码不会导致移动对象而不是复制?

#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)

输出是:

演员

复印机

我预计A1F()将被移动不会被复制。如果我稍微改变f(),它就不再是一个副本而是一个移动:

A f(int i)
{
   A a1;
   if (i != 0)
   {
      return a1;
   } …
Run Code Online (Sandbox Code Playgroud)

c++ move-semantics c++11

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

如何将转换应用于条件运算符中的位字段类型?

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 有许多转换规则,但似乎没有一个案例涵盖不同类型的泛左值和纯右值之间的转换问题。

是否将无符号位域提升为有符号整数是否由实现定义?

c++ types bit-fields

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

为什么编译器使用临时变量?

最小的代码重现问题:

#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.为何暂时?

c++ atl bstr ternary-operator visual-studio-2010

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

用三元计算重载函数

我有一个重载函数,可以采用两种参数类型:intdouble.当我使用可以返回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)

c++

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

clang和gcc之间const参考三元运算符的地址差异

我对这里发生的事情有一个模糊的想法......它与此有关,但我想知道为什么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)

c++ gcc ternary-operator clang++

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