小编Kan*_*ane的帖子

为什么对引用的 const 引用会失去其常量性?

鉴于此代码:

#include <iostream>

template<typename T>
void modify(const T &j){ j = 42; } // j has type int&

int main()
{
    int i = 10;
    modify<int&>(i); // T=int&
    std::cout << i;  // 42 is printed
}
Run Code Online (Sandbox Code Playgroud)

为什么会const T &j变成int &jif T=int&?会发生什么const?

c++ language-lawyer

46
推荐指数
3
解决办法
1599
查看次数

修改std :: for_each中的容器

标准是否明确禁止在其中修改容器std::for_each?

更具体地说,在std::list修改列表时,迭代器不会失效.因此,以下代码有效:

std::list<int> list;

list.push_front(5);
list.push_front(10);
auto it = list.end();
it--; // point to 5

std::for_each(list.begin(), list.end(), [&](int i){
    /* the line below will remove the last element in the list;
     * list will have only one element (the currently processed one);
     * list.end() is not invalidated and we exit for_each() */
    list.erase(it);
});
Run Code Online (Sandbox Code Playgroud)

这绝对是一个糟糕的代码.但这是合法的吗?

c++ language-lawyer

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

完美的转发构造函数和继承构造函数

鉴于此类层次结构:

#include <iostream>

class Base {
public:
    Base() = default;
    Base(const Base&) { std::cout << "  copy\n"; }
    
    template<typename T>
    Base(T&&) { std::cout << "  T&&\n"; }
};

class Sub : public Base {
public:
    using Base::Base;
};
Run Code Online (Sandbox Code Playgroud)

这是已知的,该代码将打印T&&:

// objects
Base varObj;
const Base constObj;
// invoking constructors
Base copy(varObj);              // T&&
Base move(std::move(constObj)); // T&&
Base number(42);                // T&&
Run Code Online (Sandbox Code Playgroud)

为什么使用Sub而不是Base“修复”问题?

// objects
Sub varObj;
const Sub constObj;
// invoking constructors …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer perfect-forwarding c++17

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

static_assert在构造函数的初始化列表之前

有一个非模板化的类,它有一个模板化的构造函数.是否可以在这样的构造函数中初始化成员变量之前检查静态断言?

例如,以下代码T::value()在检查T具有此类方法之前执行.

class MyClass
{
public:
    template<typename T>
    MyClass(const T &t)
        : m_value(t.value())
    {
        static_assert(HasValueMethod<T>::value, "T must have a value() method");
    }

private:
    int m_value;
};
Run Code Online (Sandbox Code Playgroud)

放置static_assert在构造函数的正文中工作正常,除非在成员初始化列表的所有错误消息之后打印"T必须有一个value()方法",例如:

prog.cpp: In instantiation of ‘MyClass::MyClass(const T&) [with T = int]’:
prog.cpp:24:16:   required from here
prog.cpp:12:21: error: request for member ‘value’ in ‘t’, which is of non-class type ‘const int’
         : m_value(t.value())
                   ~~^~~~~
prog.cpp:14:9: error: static assertion failed: T must have a value() method
         static_assert(HasValueMethod<T>::value, "T must have …
Run Code Online (Sandbox Code Playgroud)

c++ static-assert

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

迈尔斯与[[gnu :: pure]]一起使用的单身人士是否有UB?

以下代码是否具有未定义的行为?

[[ gnu::pure ]]
static const MyClass &myClass() noexcept
{
    static const MyClass s_myClass;
    return s_myClass;
}
Run Code Online (Sandbox Code Playgroud)

根据gcc docs,该pure属性适用于除返回值之外没有任何影响的函数,此返回值仅取决于参数和/或全局变量.

一方面,除了返回值之外,此函数没有任何可观察的效果,并且它总是返回相同的值.因此,优化多次调用此函数是完全安全的.这是我认为pure属性的用途.

另一方面,此函数需要MyClass在第一次调用时构造对象.这包括调用MyClass构造函数并将隐式的is-initialised标志设置为true.这可以算作除返回值之外的效果(尽管从外部看不到).


此代码可以工作gcc,但会clang优化MyClass构造部分并使myClass()返回成为未初始化的对象.一个clang开发商坚称这是因为不确定的行为.

请参阅此错误报告:https://bugs.llvm.org/show_bug.cgi?id = 36750(注意它说gnu::const,但使用gnu::pure产生相同的结果).

c++ gcc clang language-lawyer

3
推荐指数
2
解决办法
245
查看次数

检查返回值是否被消耗

给定一个返回重构造和重销毁对象的函数,如果不消耗函数返回值,是否有办法跳过对象构造和销毁?

HeavyObject func();
Run Code Online (Sandbox Code Playgroud)
auto res = func(); // heavy object is constructed and returned
func(); // lightweight "null" object is returned and immediately destroyed
Run Code Online (Sandbox Code Playgroud)

除了标签调度之外,有没有我可以使用的技术void func(NotConsumed);?

更新

丢弃返回值是可以的,所以[[nodiscard]]不是一个选项。客户可以决定是否要使用结果。

让我们假设func()启动一些工作并HeavyObject充当某种句柄。如果客户愿意,他们可以稍后使用它来控制/监视作业。这种句柄的构造可能涉及例如创建管道或堆内存分配。

还有其他一些func()必须使用返回值的重载,它们被标记为[[nodiscard]]. 新的重载没有此要求,但必须与现有 API 兼容。

c++ c++17

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

GMock:覆盖默认期望

在GMock中,是否有可能取代之前设定的预期?

假设,测试套件对特定方法调用具有默认期望,这是大多数测试用例所需的:

class MyClass {
public:
    virtual int foo() = 0;
};

class MyMock {
public:
    MOCK_METHOD0(foo, int());
};

class MyTest: public Test {
protected:
    void SetUp() {
        EXPECT_CALL(m_mock, foo()).WillOnce(Return(1));
    }
    MyMock m_mock;
};

TEST_F(MyTest, myTestCaseA) {
    EXPECT_EQ(1, m_mock.foo());
}
Run Code Online (Sandbox Code Playgroud)

这工作正常.但是,有些测试用例有不同的期望.如果我添加一个新的期望,如下所示,它不起作用.

TEST_F(MyTest, myTestCaseB) {
    EXPECT_CALL(m_mock, foo()).WillOnce(Return(2));
    EXPECT_EQ(2, m_mock.foo());
};
Run Code Online (Sandbox Code Playgroud)

我收到这条消息:

[ RUN      ] MyTest.myTestCaseB
/home/.../MyTest.cpp:94: Failure
Actual function call count doesn't match EXPECT_CALL(m_mock, foo())...
         Expected: to be called once
           Actual: never called - unsatisfied and active
[  FAILED  ] MyTest.myTestCaseB …
Run Code Online (Sandbox Code Playgroud)

c++ googlemock

2
推荐指数
1
解决办法
2638
查看次数