javascript

git

java

python

git-remote

c++

github

django

c#

reactjs

css

content-type

variables

var

loops

iteration

std

c++-faq

git-checkout

generator

为什么我更喜欢“显式类型的初始值设定项”成语而不是显式地给出典型值

我最近从Scott Meyers那里购买了新的有效现代C ++并阅读了。 但是我遇到一件事,这完全让我感到烦恼。

在第5项中,Scott告诉我们,使用auto是一件好事。 它可以节省键入内容,在大多数情况下为您提供正确的类型,并且可能不受类型不匹配的影响。 我完全理解这一点,并将auto也视为一件好事。

但是在第6项中,斯科特告诉我们,每个硬币都有两个面。 同样,在某些情况下,auto会推导完全错误的类型,例如 用于代理对象。

您可能已经知道此示例:

class Widget;
std::vector<bool> features(Widget w);

Widget w;

bool priority = features(w)[5]; // this is fine

auto priority = features(w)[5]; // this result in priority being a proxy
                                // to a temporary object, which will result
                                // in undefined behavior on usage after that
                                // line

到目前为止,一切都很好。

但是Scott的解决方案是所谓的“显式键入初始化器惯用语”。 这个想法是,在初始化器上像这样使用static_cast:

auto priority = static_cast<bool>(features(w)[5]);

但这不仅会导致更多类型的输入,而且您还明确声明了应该推断出的类型。 与显式给定类型相比,您基本上失去了auto的两个优点。

谁能告诉我,为什么使用这种成语会更有利?


首先要弄清楚事情,我的问题旨在指出为什么我要写:

auto priority = static_cast<bool>(features(w)[5]);

代替:

bool priority = features(w)[5];

@Sergey出现了有关该主题的有关GotW的不错的文章的链接,部分回答了我的问题。

指南:考虑声明局部变量auto x = type {expr}; 当您确实要显式提交类型时。 这是自我证明,表明代码正在明确地请求转换,它保证变量将被初始化,并且不允许意外的隐式变窄转换。 仅当确实要显式缩小范围时,才使用()代替{}。

基本上,这使我想到了一个相关的问题。 我应该选择这四种选择中的哪一种?

bool priority = features(w)[5];

auto priority = static_cast<bool>(features(w)[5]);

auto priority = bool(features(w)[5]);

auto priority = bool{features(w)[5]};

第一仍然是我的最爱。 它的输入方式更少,并且与其他三个输入方式一样明确。

保证初始化的意义并没有真正成立,因为无论如何我都是在声明变量之前先声明变量。 在快速测试中,关于缩小范围的其他争论也没有很好地解决(请参阅[http://ideone.com/GXvIIr])。

trans by 2020-08-07T07:23:38Z

为什么没有C ++ 11线程安全替代std :: localtime和std :: gmtime?

在C ++ 11中,您仍然必须使用std::localtimestd::gmtime作为间接方式来打印std::chrono::time_point。这些函数在C ++ 11引入的多线程环境中不安全使用,因为它们会返回指向内部静态结构的指针。 由于C ++ 11引入了便捷的功能std::put_time,该功能由于相同的原因几乎无法使用,这尤其令人讨厌。

为什么这是如此根本性的破坏,或者我忽略了某些东西?

trans by 2020-08-07T07:12:33Z

为什么没有将向量访问运算符指定为noexcept?

为什么没有将std::vectoroperator[]frontback成员函数指定为noexcept

trans by 2020-08-07T05:02:43Z

括号括起的初始化程序列表构造

我有以下构造函数的类Phenotype:

Phenotype(uint8 init[NUM_ITEMS]);

我可以这样创建表型:

uint8 data[] = {0,0,0,0,0};
Phenotype p(data);

但是当我尝试创建一个这样的错误时:

Phenotype p = {0,0,0,0,0};

输出:

$ make
g++ -Wall -g main.cpp -std=c++0x
main.cpp: In function ‘int main(int, char**)’:
main.cpp:109: error: no matching function for call to ‘Phenotype::Phenotype(<brace-enclosed initializer list>)’
main.cpp:37: note: candidates are: Phenotype::Phenotype(uint8*)

该错误似乎表明存在一种定义带花括号括起的初始化程序列表的构造函数的方法。 有谁知道该怎么做?

trans by 2020-08-07T04:40:58Z

在lambda中捕获完美转发的变量

template<typename T> void doSomething(T&& mStuff)
{
    auto lambda([&mStuff]{ doStuff(std::forward<T>(mStuff)); });
    lambda();
}

使用&mStuff语法捕获完美转发的mStuff变量是否正确?

还是对于完美转发的变量有特定的捕获语法?

编辑:如果完美转发的变量是参数包怎么办?

trans by 2020-08-07T03:54:24Z

c ++ 11中的指针的“自动”类型赋值是否需要“ *”?

给定我的变量是一个指针,如果我将其分配给“ auto”类型的变量,我是否指定“ *”?

std::vector<MyClass> *getVector(); //returns populated vector
//...

std::vector<MyClass> *myvector = getVector();  //assume has n items in it
auto newvar1 = myvector;

// vs:
auto *newvar2 = myvector;

//goal is to behave like this assignment:
std::vector<MyClass> *newvar3 = getVector();

我对此auto在c ++ 11中的工作方式有些困惑(这是c ++ 11的新功能,对吧?)

更新:我对上面的内容进行了修改,以更好地阐明向量是如何真正填充到函数中的,而我只是试图将返回的指针分配给变量。 对困惑感到抱歉

trans by 2020-08-07T00:58:35Z

从本质上讲,lambda关闭自身是否有效?

此Lambda递归有效吗?

#include <functional>
#include <iostream>

int main() {
   std::function<int(int)> g = [&g](int k) {
       return (k ? k * g(k-1) : 1);
   };

   std::cout << g(10); // 3628800
}

它似乎可以编译并运行良好,但我担心在初始化它的同一条语句中关闭g。 严格有效度为1-10 ...?

trans by 2020-08-06T18:51:46Z

C ++-关于填充和继承的类和结构之间的区别

以下所有内容将在GCC 9.1上使用x998-64中的Compiler Explorer在16上完成。

我有以下代码:

struct Base {
    Base() {}
    double foo;
    int bar;
};

struct Derived : public Base {
    int baz;
};

int main(int argc, char** argv)
{
    return sizeof(Derived);
}

[HTTPS://God bolt.org/在/OJ SC ZB]

如我所料,它正确地返回16foo为8个字节,bar为4个字节和baz为4个字节。这仅是因为Derived继承自Base,因此由于structclass,因此无需填充 同时包含Base16元素的类型。

我有两个问题,如下所示:

第一个问题

如果删除struct的显式构造函数,它将开始返回class,而不是Base,即在16baz之后添加填充。

[HTTPS://God bolt.org/在/0Gan5还]

我无法解释为什么拥有显式默认构造函数与具有隐式默认构造函数有什么不同。

第二个问题

如果再将Basestruct更改为class,它将变回到返回16。我也无法解释。 为什么访问修饰符会更改结构的大小?

[HTTPS://God bolt.org/在/SC Y kW l]

trans by 2020-08-05T14:36:38Z

c ++-获取自纪元以来的时间(以毫秒为单位),最好使用C ++ 11 chron

我想要的只是获取自纪元以来的时间(以毫秒为单位),并将其存储在无符号的long中。

我发现了这个相关问题。 但老实说,这不是执行这种简单任务的最简单方法,是吗? 我希望找到更简单的方法,但在std :: chrono参考中找不到任何内容。 任何建议都是最欢迎的。我不一定必须使用std::chrono,但我希望它与平台无关。

trans by 2020-08-05T07:00:24Z

等待多个期货吗?

我想一次运行相同类型的任务(工作线程),但一次不能超过一定数量的任务。 任务完成时,其结果是新任务的输入,然后可以启动该新任务。

有没有什么好方法可以在C ++ 11中使用异步/未来范例来实现这一目标?

乍一看,它看起来很简单,您只需使用以下命令即可生成多个任务:

std::future<T> result = std::async(...);

然后,运行result.get()以获取任务的异步结果。

但是,这里的问题是,将来的对象必须存储在某种队列中,并逐个等待。 但是,可以一次又一次地遍历将来的对象,以检查它们是否已经准备好,但是由于不必要的CPU负载,这是不希望的。

是否有可能以某种方式等待给定集合中的任何将来并获得结果?

到目前为止,我唯一想到的选择是没有任何异步/未来的老式方法。 具体来说,产生多个工作线程,并在每个线程的末尾将其结果推送到互斥保护的队列中,该队列通过条件变量通知等待线程,该队列已更新了更多结果。

还有其他更好的异步/未来解决方案吗?

trans by 2020-08-05T05:26:33Z

C ++-使用C ++ 11 for()循环遍历vector <unique_ptr <mytype >>

我有以下一批代码:

std::vector<std::unique_ptr<AVLTree_GeeksforGeeks>> AVLArray(100000);

/* Let's add some objects in the vector */
AVLTree_GeeksforGeeks *avl = new AVLTree_GeeksforGeeks();
avl->Insert[2]; avl->Insert[5]; AVL->Insert[0];
unique_ptr<AVLTree_GeeksforGeeks> unique_p(avl);
AVLArray[0] = move(unique_p);
/* we do this for a number of other trees, let's say another 9...
...
...
Now the vector has objects up until AVLTree[9] */

/* Let's try iterating through its valid, filled positions */
for(auto i : AVLTree )
{
   cout << "Hey there!\n";    //This loop should print 10 "Hey there"s.
}

h 在for()循环的最后部分出现编译错误。

\DataStructures2013_2014\main.cpp||In function 'int main()':|
\DataStructures2013_2014\main.cpp|158|error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = AVLTree_GeeksforGeeks; _Dp = std::default_delete<AVLTree_GeeksforGeeks>; std::unique_ptr<_Tp, _Dp> = std::unique_ptr<AVLTree_GeeksforGeeks>]'|
e:\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\unique_ptr.h|256|error: declared here|
||=== Build finished: 2 errors, 0 warnings (0 minutes, 0 seconds) ===|

关于我在做什么错的任何想法吗?

trans by 2020-08-05T01:50:00Z

C ++-最佳追加方式

这个问题已经在这里有了答案:

  • 将向量附加到向量[重复] 4个答案
std::vector<int> a;
std::vector<int> b;
std::vector<int> c;

我想通过将std::moveC++11的元素添加到a来串联这三个向量,这是最好的方法,为什么?


1)使用std::move

a.reserve(a.size() + b.size() + c.size());
a.insert(a.end(), b.begin(), b.end());
a.insert(a.end(), c.begin(), c.end());
b.clear();
c.clear();

2)使用std::move

a.reserve(a.size() + b.size() + c.size());
std::copy(b.begin(), b.end(), std::inserter(a, a.end()));
std::copy(c.begin(), c.end(), std::inserter(a, a.end()));
b.clear();
c.clear();

3)使用std::move(来自C++11):

a.reserve(a.size() + b.size() + c.size());
std::move(b.begin(), b.end(), std::inserter(a, a.end()));
std::move(c.begin(), c.end(), std::inserter(a, a.end()));
b.clear();
c.clear();
trans by 2020-08-04T21:11:51Z

性能-为什么std :: pair比std :: tup更快

这是测试代码。

元组测试:

using namespace std;

int main(){

    vector<tuple<int,int>> v;


    for (int var = 0; var < 100000000; ++var) {
        v.push_back(make_tuple(var, var));
    }
}

配对测试:

#include <vector>

using namespace std;

int main(){

    vector<pair<int,int>> v;


    for (int var = 0; var < 100000000; ++var) {
        v.push_back(make_pair(var, var));
    }
}

我通过Linux time命令进行了时间测量。结果是:

|       |   -O0   |    -O2   |
|:------|:-------:|:--------:|
| Pair  |   8.9 s |  1.60 s  |
| Tuple |  19.8 s |  1.96 s  |

我想知道,为什么O0中的这两个数据结构之间会有如此大的差异,因为它们应该非常相似。 02的差别很小。

为什么O0的差异如此之大,为什么完全没有差异?

编辑:

带v.resize()的代码

对:

#include <vector>

using namespace std;

int main(){

    vector<pair<int,int>> v;

    v.resize(100000000);

    for (int var = 0; var < 100000000; ++var) {
        v[var] = make_pair(var, var);
    }
}

元组:

#include<tuple>
#include<vector>

using namespace std;

int main(){

    vector<tuple<int,int>> v;

    v.resize(100000000);

    for (int var = 0; var < 100000000; ++var) {
        v[var] = make_tuple(var, var);
    }
}

结果:

|       |   -O0   |    -O2   |
|:------|:-------:|:--------:|
| Pair  |  5.01 s |  0.77 s  |
| Tuple |  10.6 s |  0.87 s  |

编辑:

我的系统

g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
GLIBCXX_3.4.19
trans by 2020-08-04T19:07:02Z

为什么在构造函数中修改const成员?

我很好奇为什么可以在构造函数中修改const成员。

初始化中是否有任何标准规则可以覆盖成员的“ const-ness”?

struct Bar {
    const int b = 5; // default member initialization
    Bar(int c):b(c) {}
};

Bar *b = new Bar(2); // Problem: Bar::b is modified to 2
                     // was expecting it to be an error

有任何想法吗?

trans by 2020-08-02T22:58:24Z

为什么C ++ 11不支持匿名结构而C11支持呢?

C11支持匿名结构,如下所示:

struct Foo
{
    struct
    {
        size_t x, y;
    };
};
struct Foo f;
f.x = 17;
f.y = 42;

基本上,将此类struct的成员视为它们是封闭的structunion的成员(递归,如果封闭结构本身是匿名的)。

C ++ 11不包含匿名结构的基本原理是什么? 当然,它们仅是非常有用的(主要是在联合体内,以消除struct的标识符的键入)。 但是它们似乎是对规范的明显补充(并且已经由许多编译器实现),必须对它们进行讨论,至少要保留与C11标准的兼容性。 那么为什么不添加呢?

trans by 2020-08-02T13:42:34Z

C ++-std :: bind是否应与boost :: asio兼容?

我正在尝试使boost :: asio示例之一适合在可能的情况下使用c ++ 11 / TR1库。 原始代码如下所示:

void start_accept()
{ 
  tcp_connection::pointer new_connection =
    tcp_connection::create(acceptor_.get_io_service());

  acceptor_.async_accept(new_connection->socket(),
      boost::bind(&tcp_server::handle_accept, this, new_connection,
         boost::asio::placeholders::error));
}

如果我将boost::bind替换为std::bind,如下所示:

void start_accept()
{ 
  tcp_connection::pointer new_connection =
    tcp_connection::create(acceptor_.get_io_service());

  acceptor_.async_accept(new_connection->socket(),
      std::bind(&tcp_server::handle_accept, this, new_connection,
                 boost::asio::placeholders::error ) );
      // std::bind(&tcp_server::handle_accept, this, new_connection, _1 ) );
}

我收到一条大错误消息,结尾为:

/usr/include/c++/4.4/tr1_impl/functional:1137: error: return-statement with a value, in function returning 'void'

我正在使用带有gcc版本1.47的gcc版本4.4

我期望boost :: bind和std :: bind是可互换的。

trans by 2020-08-02T13:27:04Z

为什么嵌套的可变参数模板无效的参数?

如果我定义了Bar模板struct,该模板接受模板参数:

template <template <int,bool,char> class>
struct Bar {};

我可以使用Bar模板(例如struct)实例化它:

template <int,bool,char> struct Zod {};
Bar<Zod> a;

我也可以使用嵌套的Bar模板(例如struct)实例化它:

struct GHI {
  template <int,bool,char>
  struct JKL {};
};
Bar <GHI::JKL> b;

为什么我不能使用嵌套的可变参数struct模板(例如DEF)实例化Bar ?:

template <typename ...Ts>
struct ABC {
  template <Ts ...>
  struct DEF {};
};

Bar<ABC<int,bool,char>::DEF> c;

G ++ 4.9.2抱怨类型/值不匹配; 而Clang 3.4.2的错误报告模板模板参数具有与其相应模板模板参数不同的模板参数。

trans by 2020-08-02T13:23:54Z

为什么std :: declval添加引用?

decltype是一个编译时实用程序,用于构造表达式以确定其类型。 定义如下:

template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;

会不会更简单?

template< class T >
T declval() noexcept;

引用返回类型的优点是什么? 并且不应该将其命名为decltype吗?

我发现的最早的历史示例是n2958,它调用了函数decltype,但始终已返回引用。

请注意,decltype的操作数不需要具有可访问的析构函数,即在语义上不会将其检查为完整表达式。

template< typename t >
t declprval() noexcept;

class c { ~ c (); };
decltype ( declprval< c >() ) * p = nullptr; // OK
trans by 2020-08-01T21:48:47Z

c ++-Meyers如何实现Singleton实际上是Singleton

我已经阅读了很多有关Singleton的内容,何时应该使用不应该使用它们,以及如何安全地实现它们。 我正在用C ++ 11编写,并且遇到了迈耶的单例的懒惰初始化实现。

该实现是:

static Singleton& instance()
{
     static Singleton s;
     return s;
}

我从SO上的其他问题中了解到线程安全性如何,但是我不明白的是这实际上是单例模式。 我已经用其他语言实现了单例,并且这些总是以类似于Wikipedia的示例的形式结束:

public class SingletonDemo {
        private static volatile SingletonDemo instance = null;

        private SingletonDemo() {       }

        public static SingletonDemo getInstance() {
                if (instance == null) {
                        synchronized (SingletonDemo .class){
                                if (instance == null) {
                                        instance = new SingletonDemo ();
                                }
                      }
                }
                return instance;
        }
}

当我看第二个示例时,这是一个单例非常直观,因为该类持有对自身一个实例的引用,并且仅返回该实例。 但是,在第一个示例中,我不明白这如何防止对象存在两个实例。 所以我的问题是:

  1. 第一个实现如何执行单例模式? 我认为它与static关键字有关,但我希望有人可以向我深入说明幕后情况。
  2. 在这两种实现方式之间,是否有一种比另一种更好? 优缺点都有什么?

谢谢你的帮助,

trans by 2020-08-01T18:35:44Z

C ++-标准的原子布尔值和原子标记之间的区别

我不了解2992280211821121167616变量,但了解该标准提供的29922802118211676676(怪异的权利!)。 然而,有一件事引起了我的注意:标准提供了两种看似相同的原子类型,以下列出:

  1. std::atomic bool type类型

  2. std::atomic bool type type

还以2992280211821167667616的示例为例-

std :: atomic_flag是原子布尔类型。 与std :: atomic的所有专业不同,它保证是无锁的。 与std :: atomic不同,std :: atomic_flag不提供加载或存储操作。

我不明白。 是否不能保证29922802118211676676是无锁的? 那不是原子的还是什么?

那么两者之间有什么区别,什么时候应该使用?

trans by 2020-08-01T14:19:47Z

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 下一页 共31页