相关疑难解决方法(0)

当从函数返回为"const"时,为什么原始类型和用户定义类型的行为不同?

#include <iostream>

using namespace std;

template<typename T>
void f(T&&) { cout << "f(T&&)" << endl; }

template<typename T>
void f(const T&&) { cout << "f(const T&&)" << endl; }

struct A {};
const A g1() { return {}; }
const int g2() { return {}; }

int main()
{
    f(g1()); // outputs "f(const T&&)" as expected.
    f(g2()); // outputs "f(T&&)" not as expected.
}
Run Code Online (Sandbox Code Playgroud)

问题描述嵌入在代码中.我的编译器是clang 5.0.

我只是好奇:

在这种情况下,为什么C++会以不同方式处理内置类型和自定义类型?

c++ standards overloading overload-resolution c++11

41
推荐指数
3
解决办法
2065
查看次数

对于非内置类型,使用const值返回函数有什么用例?

最近我读过,从函数返回值来为非内置类型限定返回类型const是有意义的,例如:

const Result operation() {
    //..do something..
    return Result(..);
}
Run Code Online (Sandbox Code Playgroud)

我很难理解这个的好处,一旦对象被返回肯定是调用者的选择来决定返回的对象是否应该是const?

c++ const-correctness

40
推荐指数
4
解决办法
7710
查看次数

为什么分配给substr调用的结果不是编译器错误?

我刚刚发现了最令人困惑的错误,我不明白为什么编译器没有为我标记它.如果我写下面的内容:

string s = "abcdefghijkl";
cout << s << endl;

s.substr(2,3) = "foo";
s.substr(8,1) = '.';
s.substr(9,1) = 4;
cout << s << endl;
Run Code Online (Sandbox Code Playgroud)

编译器对此没有任何问题,并且赋值语句似乎根据打印出的内容没有任何效果.相反,

s.front() = 'x';
Run Code Online (Sandbox Code Playgroud)

具有我期望的效果(因为front返回对字符的引用)改变底层字符串,和

s.length() = 4;
Run Code Online (Sandbox Code Playgroud)

也有产生编译器错误的预期效果,抱怨你不能分配给不是左值的东西,因为length返回一个整数.(好吧,size_t无论如何.)

那么......为什么编译器不会抱怨分配给substr调用的结果呢?它返回一个字符串值,而不是引用,所以它不应该是可赋值的,对吧?但我在g++(6.2.1)和clang++(3.9.0)中尝试了这个,所以它似乎不是一个bug,它似乎也不敏感C++版本(试过03,11,14) ).

c++ string substring lvalue

29
推荐指数
3
解决办法
2429
查看次数

是否有"空"的简明对立面?

字符串类的接口通常具有名为IsEmpty(VCL)或empty(STL)的方法.这是绝对合理的,因为它是一个特殊情况,但使用这些方法的代码通常必须否定这个谓词,这导致"光学(甚至心理)开销"(感叹号不是很明显,特别是在一个左括号后) ).例如,请参阅此(简化)代码:

/// format an optional time specification for output
std::string fmtTime(const std::string& start, const std::string& end)
{
    std::string time;
    if (!start.empty() || !end.empty()) {
        if (!start.empty() && !end.empty()) {
            time = "from "+start+" to "+end;
        } else {
            if (end.empty()) {
                time = "since "+start;
            } else {
                time = "until "+end;
            }
        }
    }
    return time;
}
Run Code Online (Sandbox Code Playgroud)

它有四个否定,因为空案例是要跳过的.在设计界面时,我经常会观察到这种否定,这不是一个大问题,但它很烦人.我只想支持编写易于理解且易于阅读的代码.我希望你能理解我的观点.

也许我只是失明了:你如何解决上述问题?


编辑:在阅读了一些评论后,我认为原始代码使用System::AnsiString …

c++ string api coding-style readability

20
推荐指数
4
解决办法
2117
查看次数

使用标量类型的"const"的好处?(例如"const double"或"const int")

///////////////////////////////////////
class A {
    ...
    const double funA(void)
    {...}
};

A a;
double x = a.funA(); 
// although the intention is to
// enforce the return value to be const and cannot be
// modified, it has little effect in the real world.

class A2 {
    ...
    double funB(void)
    {...}
};

///////////////////////////////////////
class A {
    void setA(const double d)
    { // now you cannot change the value of d, so what?
      // From my point of view, it is NOT …
Run Code Online (Sandbox Code Playgroud)

c++

10
推荐指数
1
解决办法
5253
查看次数

通过const值返回会影响返回值优化吗?

考虑这个功能

const std::string f()
{
    return "hello";
}
Run Code Online (Sandbox Code Playgroud)

和电话

std::string x = f();
Run Code Online (Sandbox Code Playgroud)

无论值返回类型是否为const,返回值是否为const,都会阻止编译器执行返回值优化?

我对RVO的理解是返回的对象直接构造在函数外部的变量中.但是,如果返回类型是const T,这与a不同T,那么RVO会被阻止吗?

c++ return-value-optimization rvo

10
推荐指数
0
解决办法
839
查看次数

从函数返回一个不可变的POD类

上下文

我正在开发一个由不同模块组合而成的大型项目.我们有exporter一个模板功能export<T>(const T& obj),其工作只是在POD类型(它static_assertis_pod,如果你很好奇).目前我坐在系统的一部分,负责编目由元数据描述的一些实体(它们的类型无关紧要).元数据本身由一些被调用的函数返回metadata describe(const entity& obj),并且在返回后应该是不可变的.当然,函数本身将metadata成员设置在其体内.

问题

由于上面提到的事实,我需要设计一个const POD类型.由于POD类型不能具有用户定义的构造函数,因此成员变量本身不能const.const直接从值返回变量describe 是没有意义的(或者至少可以说没有帮助).

有针对性的解决方案

所以基本上我到目前为止所想到的是:

  • 超载exporter.export<T>(...)metadata,但因为它只能解决当前类的问题,这不是一个真正的解决方案,同时在最终产品中会出现许多类型的实体(我不是在谈论.重载函数用于所有类型的似乎只是错误.
  • 设计一个immutable包装并从中返回describe.这就是我目前正在做的事情,因为我无法找到解决问题的更好方法.包装器提供隐式转换const &T并存储T自身内部,因此可以直接传递给export函数.

有没有更好的方法从函数返回不可变的POD类?我错过了什么吗?为简单起见,假设假设metadata定义如下:

struct metadata{
    int parameter1;
    time_t parameter2;
};
Run Code Online (Sandbox Code Playgroud)

并按describe如下方式工作(目前,跳过当前的解决方案):

metadata describe(const entity& obj){
   metadata …
Run Code Online (Sandbox Code Playgroud)

c++ design-patterns immutability c++11

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

转换为`const Y`不适用于clang上的`R &&`

以下代码编译良好g++ (GCC) 4.7.1 20120721,但最近构建失败clang version 3.2 (trunk).

struct Y {};

struct X {
  operator const Y() const { return Y(); }
};

void f(Y&& y) {}

int main()
{
  f(X());
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

将转换运算符更改operator Y() const为足以使代码在两个编译器上进行编译.

在这种情况下,哪个编译器实际上符合标准?标准实际上对此有何看法?

请求的逐字错误:

bla.cpp:14:5: error: no viable conversion from 'X' to 'Y'
  f(X());
    ^~~
bla.cpp:1:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'X' to
      'const Y &' for 1st argument
struct Y { …
Run Code Online (Sandbox Code Playgroud)

c++ g++ clang move-semantics c++11

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

应该在c ++中返回const数据类型后增加运算符重载

对于像int这样的基本数据类型,代码片段会出现编译错误

i++ = 2;
Run Code Online (Sandbox Code Playgroud)

所以显然i++不是左值

但是当用c ++重载自定义类时,大多数人都认为post增量运算符的签名应该是这样的

Date Date::operator++(int) {
    Date temp = *this;
    // do increment
    return temp;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么不应该返回类型const Date而不是Date原始类型.

c++ operator-overloading

5
推荐指数
0
解决办法
88
查看次数

为什么const变量可以修改?

我正在编写一本关于运算符重载的示例教科书,它让我想知道返回"常量值"(例如operator+).据我了解,如果我作为a返回任何内容const,则以后无法修改.说我有这个粗略的例子:

#include <iostream>
using namespace std;

class Temp {
    private:
        int val;
    public:
        Temp(){};

        Temp(int v):val(v){};

        const Temp operator+(const Temp& rhs) const {
            return Temp(this->val + rhs.val);
        }
        int getVal() { return this->val; }
        void setVal(int v) { this->val = v; } 
};

int main() {
    Temp t1, t2, t3;
    t1 = Temp(4);
    t2 = Temp(5);
    t3 = t1 + t2;
    cout << t3.getVal() << endl;
    t3.setVal(100);
    cout << t3.getVal() << endl;
}
Run Code Online (Sandbox Code Playgroud)

之后t3 = …

c++ operator-overloading

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