小编son*_*yao的帖子

将函数返回值传递给参考参数导致GCC中的编译错误

假设我声明了这个函数:

class A
{
...
 public:
   void setRect(Rect & rct);
...
}
Run Code Online (Sandbox Code Playgroud)

该成员setRect被称为这样.

A a;
a.setRect(Some_Func_Return_A_Rect_Object());
Run Code Online (Sandbox Code Playgroud)

gcc编译器抱怨找不到匹配的函数A :: setRect(Rect)

如果我这样打电话,那很好:

A a;
Rect rct = Some_Func_Return_A_Rect_Object();
a.setRect(rct);
Run Code Online (Sandbox Code Playgroud)

标准是否对此有所说明?GCC只是不允许第一种调用setRect()函数的方式?

c++ gcc reference pass-by-reference

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

为什么编译器在使用CRTP时看不到基类的方法

我有以下代码:

struct Iface
{
    virtual int Read() = 0;

    int Read(int x) {
        return Read() + x;
    }
};

template <typename Impl>
struct Crtp : public Iface
{
    virtual int Read() {
        return static_cast<Impl&>(*this).ReadImpl();
    }
    //using Iface::Read;
};

struct IfaceImpl : public Crtp<IfaceImpl>
{
    int ReadImpl() {
        return 42;
    }
};

int main()
{
    IfaceImpl impl;
    impl.Read(24); // compilation error

    Iface& iface = impl;
    iface.Read(24); // always compiles successfully
}
Run Code Online (Sandbox Code Playgroud)

msvc,gcc和clang都拒绝这个代码,他们找不到方法 Read(int x)

但是如果我using Iface::ReadCrtp我的代码中取消注释成功编译.

请注意,如果我参考Iface,我可以打电话 …

c++ inheritance crtp

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

未知模板类型的默认值或零值

假设模板功能

template<typename T>
T foo(){
  // ...
  // Error occured
  if(error)
     return 0;
  // ...
}
Run Code Online (Sandbox Code Playgroud)

这应该返回0,0.0f,nullptr,...取决于类型T,当错误发生.

如何获取0未知模板类型?在C#中你可以写default(T)这个来做.

如何在C++中执行此操作?

c++ templates default default-value

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

为什么派生类不能通过指向base的指针访问其基类的受保护成员?

这是代码:

class TestA
{
protected:
    int test=12;

public:
    TestA() {
        cout << "test a: " << test << endl;
    }
    ~TestA() {
    }
};

class TestB : public TestA
{   
public:
    TestB(TestA *testA) {
        cout << "test b: " << testA->test;
    }
    ~TestB() {
    }
};

int main ()
{
    TestA *pTestA=new TestA();
    TestB *pTestB=new TestB(pTestA);
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试protected使用指向TestA类型对象的指针(因此,实例TestA)来访问成员.TestB也来源于TestA

为什么我无法访问它?它只能在我需要它的类中"访问"吗?不在外面使用指针/直接声明?

c++ inheritance scope protected

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

正确的朋友模板功能的语法

在"C++编程语言"第四版 - 第23.4.7章"朋友"中,我找到了以下示例(我稍微修改了它以仅显示相关部分):

template<typename T>
class Vector {
public:
    friend Vector operator*<>(const Vector& v, int f); 
                           ^^ ~~~~ ?
};

template<typename T>
Vector<T> operator*(const Vector<T>& v, int f) {
    return v;
}
Run Code Online (Sandbox Code Playgroud)

我试图编译它,但我得到以下错误(clang):

main.cpp:8:20: error: friends can only be classes or functions
        friend Vector operator*<>(const Vector& v, int f); 
                      ^
main.cpp:8:29: error: expected ';' at end of declaration list
        friend Vector operator*<>(const Vector& v, int f); 
                               ^
                               ;
2 errors generated.
Run Code Online (Sandbox Code Playgroud)

书解释说:

需要友元函数名称后面的<>来表明朋友是模板函数.如果没有<>,则假定为非模板函数.

这就是全部.

如果没有<>此代码编译,但在使用operator*时(例如Vector<int> v; v*12; …

c++ templates friend

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

返回本地创建的const char*

#include <iostream>


const char* fun()
{
    const char* x = "abc";
    std::cout << "x = " << x << "\n";
    return x;
}


int main(int arc, char** argv)
{
    const char* y = fun();
    std::cout << "y = " << y << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上运行它给出:

x = abc

y = abc
Run Code Online (Sandbox Code Playgroud)

fun(),x(一个局部变量)被分配字面创建本地一个字符串的地址,然而,当该函数返回时,该数据指向y是作为通过指向同一x即使x超出范围.

有人可以详细解释这里发生了什么吗?

c++ pointers return lifetime

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

C++中两个复制构造函数调用之间的区别是什么?

请看以下代码:

class Foo    
{ 
public:  
    Foo(){}  
    explicit Foo(const Foo &){}  
};  
int main()  
{  
    Foo foo1;  
    Foo foo2(foo1);  
    Foo foo3 = foo1; //can not compile    
    return 0;  
}  
Run Code Online (Sandbox Code Playgroud)

为什么Foo foo3 = foo1;无法编译,两个复制构造函数调用之间有什么区别?
ps:我的编译器工具是GCC4.8.2

c++ initialization

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

为什么在std :: move之后将成员unique_ptr &lt;&gt;保留为非空值?

当我将a unique_ptr<>移入引发的函数中时,move -from指针不为空。这是正常现象吗?

这是两个显示该行为的测试程序。我可以在类的析构函数中观察到唯一的指针:

#include <memory>
#include <iostream>

void f(std::unique_ptr<int> &&) { throw "fail"; }
struct except_move_tester
{
    std::unique_ptr<int> x;
    except_move_tester()
      : x(std::make_unique<int>(0))
    {}
    ~except_move_tester() { std::cout << "x at destructor: " << x.get() << std::endl; }
    void g()
    {
        std::cout << "x at g: " << x.get() << std::endl;
        f(std::move(x));
    }
};

int main()
{
    try {
        except_move_tester t;
        t.g();
    } catch (...) {}
}
Run Code Online (Sandbox Code Playgroud)

运行时给出的输出:

x at g: 0x7f818b402ac0
x at destructor: 0x7f818b402ac0
Run Code Online (Sandbox Code Playgroud)

如果我按如下方式修改上面的清单(只是在函数调用的位置添加了一个临时名称),那么我通常会期望得到异常安全行为:

#include <memory>
#include …
Run Code Online (Sandbox Code Playgroud)

c++ exception unique-ptr move-semantics c++14

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

C++ countof 成员数组的实现

我正在尝试使用 C++ 模板创建与 Visual Studio _countof 宏等效的内容。以下是我建议的定义:

\n\n
template<typename T, size_t N>\ninline constexpr size_t countof(T const (&array)[N]) {\n    return N;\n}\ntemplate<typename T, typename U, size_t N>\ninline constexpr size_t countof(T const (U::&array)[N]) {\n    return N;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

上面的第二个声明是尝试修复以下代码,该代码在 g++ 9 中生成编译时错误,并显示消息:“错误:无效使用非静态数据成员 \xe2\x80\x98foo::bar\xe2\ x80\x99":

\n\n
struct foo {\n    int const bar[4];\n    static_assert(countof(bar) == 4);\n};\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,当我添加第二个定义并将断言更改为 use 时foo::bar,g++ 生成错误:“错误:\xe2\x80\x98template constexpr const size_t countof\xe2\x80\x99 与先前的声明冲突”。

\n\n

我可以更改代码以使用指向成员的指针(而不是对成员的引用),但这似乎是不必要的。有谁知道一种方法来制作countof仅在传递数组时才编译的版本,并且以合理的方式适用于自由数组和成员变量数组?

\n

c++ templates g++ c++14

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

在右值参考参数上使用std :: move的原因

我正在读一本关于用C ++实现的数据结构的书,我不明白代码片段吗?它是向量类的一部分

void push_back(object &&x) {
        //do something
        objects[size++] = std::move(x);
    }
Run Code Online (Sandbox Code Playgroud)

我知道std::move返回对象的右值引用,但是push_back成员函数已经具有右值引用x作为参数,std::move这里不是不必要的吗?

另一个问题是,如果我们有一个类对象的右值引用,std::move如果要调用move而不是copy right 还是需要在其成员上使用它?像下面的代码:

A& operator=(A&& other) {
     member = std::move(other.member);
     return *this;
}
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference move-semantics c++11 value-categories

5
推荐指数
2
解决办法
106
查看次数