小编Zeb*_*ish的帖子

如果没有默认构造函数,为什么不编译?

我可以做这个:

#include <iostream>

int counter;

int main()
{
    struct Boo
    {
        Boo(int num)
        {
            ++counter;
            if (rand() % num < 7) Boo(8);
        }
    };

    Boo(8);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将编译正常,我的计数器结果是21.但是,当我尝试创建Boo传递构造函数参数而不是整数文字的对象时,我得到一个编译错误:

#include <iostream>

int counter;

int main()
{
    struct Boo
    {
        Boo(int num)
        {
            ++counter;
            if (rand() % num < 7) Boo(num); // No default constructor 
                                            // exists for Boo
        }
    };

    Boo(8);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如何在第二个示例中调用默认构造函数,而不是在第一个示例中调用?这是我在Visual Studio 2017上遇到的错误.

在线C++编译器onlineGDB我得到错误:

error: no matching function for call to ‘main()::Boo::Boo()’ …
Run Code Online (Sandbox Code Playgroud)

c++ constructor scope default-constructor most-vexing-parse

70
推荐指数
2
解决办法
5193
查看次数

声明/定义为C和C++中的语句

当这不能在C中编译时我很困惑:

int main()
{
    for (int i = 0; i < 4; ++i)
        int a = 5; // A dependent statement may not be declaration

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经习惯了将要编译的C++.我只是愣了一会儿,直到我记得这里的答案是关于如何在C和C++中将不同的东西视为"陈述".这是关于switch语句的.for循环括号后面的"语句"必须同时出现在C和C++中.这可以在添加分号或创建{}波浪形支架块的情况下完成.

在C++中"int a = 7;" 被视为声明,定义和初始化.CI认为它也被认为是所有这些,但在C中它不被视为"声明".

有人可以准确地澄清为什么在C中这不是一个陈述,而在C++中它是?这让我对一个陈述的概念感到困惑,因为一种语言说的是,而另一种语言则说不是,所以我有点困惑.

c c++ if-statement language-lawyer

38
推荐指数
3
解决办法
2673
查看次数

我可以一口气检查一小撮布尔型吗?

有一个类似的问题在这里,但在这一问题的用户似乎有一个更大的阵列,或载体。如果我有:

bool boolArray[4];
Run Code Online (Sandbox Code Playgroud)

我想检查所有元素是否为假,我可以分别检查[0],[1],[2]和[3],也可以循环遍历。由于(据我所知)false应该具有值0,而除0以外的其他任何东西都为true,所以我想到了简单地做:

if ( *(int*) boolArray) { }
Run Code Online (Sandbox Code Playgroud)

这行得通,但是我意识到它依赖于布尔值是一个字节,整数是四个字节。如果我强制转换为(std :: uint32_t)可以,还是一个坏主意?我刚好在一个数组中有3或4个布尔值,并且想知道这是否安全,如果不是,那么是否有更好的方法可以做到。

另外,如果我最终得到超过4个布尔值,但少于8个布尔值,那么我可以使用std :: uint64_t或unsigned long long之类的东西做同样的事情吗?

c++ arrays casting boolean

28
推荐指数
2
解决办法
2625
查看次数

我可以在一行上写一个带有变量声明的if语句吗?

我想知道是否有办法把它放在一条线上?

if (auto r = getGlobalObjectByName(word)) r->doSomething; // This works fine

if (!auto r = getGlobalObjectByName(word)) r->doSomething; // Says "expected an expression"

if (auto r = getGlobalObjectByName(word) == false) r->doSomething; // Also doesn't work.
Run Code Online (Sandbox Code Playgroud)

我也尝试用额外的括号围绕它,但这似乎不起作用.我发现这在一条线上非常方便.

c++ if-statement

26
推荐指数
2
解决办法
4496
查看次数

为什么我不能用左值初始化这个 std::vector ?

我遇到了一个有趣的问题,我无法理解发生了什么:

/* I WANT 6 ELEMENTS */
int lvalue = 6;

std::vector<int*> myvector { 6 }; /* WORKS FINE */
std::vector<int*> myvector{ lvalue }; /* DOESN'T WORK */
/* Element '1': conversion from 'int' to 'const unsigned __int64 requires a narrowing conversion */
Run Code Online (Sandbox Code Playgroud)

据我所知,我提供的单个整数参数可以解释为使用 argument 调用构造函数size_type count,也可以解释为采用初始值设定项列表的构造函数。似乎initialiser_list只有当我提供左值时才调用构造函数,而size_t count当我给出右值int(好吧,至少是一个文字)时才调用构造函数。为什么是这样?

这也意味着:

int num_elements = 6;
std::vector<int> myvector{num_elements};
Run Code Online (Sandbox Code Playgroud)

结果仅是大小为 的向量1

std::vector<int> myvector(num_elements);
Run Code Online (Sandbox Code Playgroud)

结果是一个 size 的向量num_elements,但我认为应该避免这种初始化,因为偶尔会遇到最令人烦恼的解析问题。

c++ language-lawyer narrowing

26
推荐指数
1
解决办法
1703
查看次数

使用std :: vector,为什么&vec [0]未定义行为,但vec.data()安全吗?

我一直在isocpp.org通过阅读FAQ在"链接到此处",并在整个谨慎传来,有std::vector:

std::vector<int> v;
auto a = &v[0]; // Is undefined behaviour but
auto a = v.data(); // Is safe
Run Code Online (Sandbox Code Playgroud)

从实际网站:

void g()
{
  std::vector<Foo> v;
  // ...
  f(v.begin(), v.size());  // Error, not guaranteed to be the same as &v[0]
    ????????? // Cough, choke, gag; use v.data() instead
}
Run Code Online (Sandbox Code Playgroud)

此外,&v[0]如果std::vectorstd::array为空,则使用未定义的行为,而使用该.data() 函数始终是安全的.

我不确定我是否完全理解这一点.::data()返回指向数组开头的指针,并&[0]返回开头的地址.我没有看到这里的区别,我不认为这&[0]是解除引用任何东西(即,不读取元素0处的内存).在Visual Studio中调试构建访问下标[0]导致断言失败,但在发布模式下它没有说什么.此外,两种情况下的地址对于默认构造矢量都是0.

另外我不明白关于::begin()不保证是相同的评论::operator[0].我假设对于向量,begin()迭代器中的原始指针::data(),并且 …

c++ arrays vector undefined-behavior c++11

25
推荐指数
1
解决办法
1924
查看次数

为什么这个std :: vector :: emplace_back会失败?

我遇到一个编译错误,说:

试图引用已删除的功能

#include <iostream>
#include <vector>

template <typename T>
struct Container
{
    Container() = default;
    Container(const Container& other) = delete;
    Container(T* ptr) : ptr(ptr) {}
    T* ptr;
    ~Container() { delete ptr; }

};

struct Foo { Foo(int a, int b) {} };

int main()
{
    std::vector<Container<Foo>> myvector;
    myvector.push_back(new Foo(1, 2)); // I understand why this doesn't work.
    myvector.emplace_back((new Foo(1, 2))); // I don't understand why this fails

}
Run Code Online (Sandbox Code Playgroud)

我理解为什么它会在我做的时候尝试引用已删除的构造函数std::vector::push_back(),因为这会复制并需要调用我删除的复制构造函数.

但是std::vector::emplace_back()应该采用它所拥有的类型的构造函数参数.当我向后移动时,我给它一个指向a的指针Foo,这应该转发给Container::Container(T* …

c++ constructor stdvector

20
推荐指数
1
解决办法
1088
查看次数

如何传递对模板类型名参数的引用

有没有办法将引用作为参数传递给模板类型名参数?我的意思是这样,而不是传递 int,例如,传递对 int 的引用。

template <typename T>
struct Foo
{
    Foo(T arg) : ptr(arg) {}
    T ptr;
};

int main() 
{
    int* a = new int(6);
    Foo<decltype(a)> foo1(a); // ptr is a copy of a pointer
    Foo<decltype(&a)> foo1(&a); // ptr seems to be a pointer to a pointer
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过在类中将它设为 T& 来使 'ptr' 成员成为对指针的引用,但我想知道这是否可以通过传递给模板参数的参数来完成。

c++ templates

16
推荐指数
1
解决办法
641
查看次数

什么是这个奇怪的复制构造错误抱怨?

我在Visual Studio 2017上.最近,因为我不喜欢C++的不符合标准,所以我继续并禁用了选项中的非标准语言扩展.到现在为止还挺好.现在我有一个问题.

#include <iostream>
#include <vector>


struct Vertex
{
    Vertex(float pos) { }
    Vertex(Vertex& other) { }
};

std::vector<Vertex> arrayOfVertices;

int main()
{
    arrayOfVertices.emplace_back(7.f);
}
Run Code Online (Sandbox Code Playgroud)

这不会在Visual Studio中编译,它给出的唯一错误是:

"编译器中发生内部错误"

如果我启用语言扩展,它编译得很好.如果我禁用语言扩展并使复制构造函数采用const Vertex&它编译好.

所以我在一些在线编译器上尝试了GCC,如果复制构造函数没有采用const引用参数,它将无法编译,从而产生各种错误.似乎最有意义的是:

错误:从'Vertex'类型的右值开始无效初始化'Vertex&'类型的非const引用

我认为复制构造函数不必是const,在我的情况下我想修改另一个引用中的东西.我知道非const参数不能采用r值引用,但我测试了它,结果发现在vector::emplace_back()拷贝构造函数中根本没有调用:

#include <iostream>
#include <vector>

struct Vertex
{
    Vertex(float pos) 
    { 
        std::cout << "Calling constructor\n";
    }
    Vertex(const Vertex& other) 
    { 
        std::cout << "Calling copy constructor\n";
    }
};

std::vector<Vertex> arrayOfVertices;

int main()
{
    arrayOfVertices.emplace_back(7.f); // Normal constructor called if const,
                                       // doesn't compile if …
Run Code Online (Sandbox Code Playgroud)

c++ copy-constructor const-reference c++11

15
推荐指数
2
解决办法
2019
查看次数

成员函数的函数签名是什么?

我无法理解函数签名和指针.

struct myStruct
{
    static void staticFunc(){};
    void nonstaticFunc(){};
};

int main()
{
    void (*p)();     // Pointer to function with signature void();
    p = &myStruct::staticFunc;    // Works fine
    p = &myStruct::nonstaticFunc; // Type mismatch   
}
Run Code Online (Sandbox Code Playgroud)

我的编译器说类型myStruct::nonstaticFunc()是void (myStruct::*)(),但不是指向它的指针类型?

我问,因为当你创建一个std::function对象时,你传递了你想要它指向的函数的函数签名,比如:

std::function<void()> funcPtr;      // Pointer to function with signature void()
not 
std::function<void(*)()> funcPtr;
Run Code Online (Sandbox Code Playgroud)

如果我不得不根据void()我会说的模式猜测:

void myStruct::();
or
void (myStruct::)();
Run Code Online (Sandbox Code Playgroud)

但这不对.我不明白为什么我应该添加一个星号,因为它是非静态的而不是静态的.换句话说,指针void(* )()指向带签名的函数void(),而指针void(myStruct::*)()指向带签名的函数是什么?

c++ pointers function

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