标签: c++

为什么在调用std :: vector :: emplace_back()时调用复制构造函数?

我的理解是,目的std::vector::emplace_back()避免调用复制构造函数,而是直接构造对象.

请考虑以下代码:

#include <memory>
#include <vector>
#include <boost/filesystem.hpp>

using namespace std;

struct stuff
{
    unique_ptr<int> dummy_ptr;
    boost::filesystem::path dummy_path;
    stuff(unique_ptr<int> && dummy_ptr_,
          boost::filesystem::path const & dummy_path_)
        : dummy_ptr(std::move(dummy_ptr_))
        , dummy_path(dummy_path_)
    {}
};

int main(int argc, const char * argv[])
{

    vector<stuff> myvec;

    // Do not pass an object of type "stuff" to the "emplace_back()" function.
    // ... Instead, pass **arguments** that would be passed
    // ... to "stuff"'s constructor,
    // ... and expect the "stuff" object to …
Run Code Online (Sandbox Code Playgroud)

c++ c++11

24
推荐指数
1
解决办法
4581
查看次数

这个GCC优化不正确吗?

我有一个functor,它接受一个值,将其转换为double,获取日志并将值转换回原始类型.出于此问题的目的,原始和输出类型是float.这是原始的C++代码:

return static_cast< TOutput >( std::log( static_cast< double >( A ) ) )
Run Code Online (Sandbox Code Playgroud)

当我在调试模式下编译时,一切都按预期进行,GCC调用底层log函数:

  51:/myfile.h ****     return static_cast< TOutput >( std::log( static_cast< double >( A ) ) );
 219133                 .loc 112 51 0
 219134 0010 488B45F0     movq  -16(%rbp), %rax # A, tmp64
 219135 0014 F30F1000     movss (%rax), %xmm0 # *A_1(D), D.237346
 219136 0018 0F14C0       unpcklps  %xmm0, %xmm0  # D.237346, D.237346
 219137 001b 0F5AC0       cvtps2pd  %xmm0, %xmm0  # D.237346, D.237347
 219138 001e E8000000     call  log #
 219138      00
 219139 …
Run Code Online (Sandbox Code Playgroud)

c++ linux floating-point assembly gcc

24
推荐指数
1
解决办法
1848
查看次数

为什么自动返回类型会改变重载分辨率?

感谢decltype作为返回类型,C++ 11使得引入装饰器非常容易.例如,考虑这个类:

struct base
{
  void fun(unsigned) {}
};
Run Code Online (Sandbox Code Playgroud)

我想用其他功能来装饰它,因为我会用不同种类的装饰做几次,所以我首先介绍一个decorator简单地转发所有内容的课程base.在真实的代码中,这是通过以下方式完成的,std::shared_ptr这样我就可以删除装饰并恢复"裸"对象,并且所有内容都是模板化的.

#include <utility> // std::forward
struct decorator
{
  base b;

  template <typename... Args>
  auto
  fun(Args&&... args)
    -> decltype(b.fun(std::forward<Args>(args)...))
  {
    return b.fun(std::forward<Args>(args)...);
  }
};
Run Code Online (Sandbox Code Playgroud)

完美的转发,decltype真是太棒了.在实际代码中,我实际上使用的是一个只需要函数名称的宏,其余的都是样板文件.

然后,我可以引入一个derived为我的对象添加功能的类(derived不正确,同意,但它有助于理解这derived是一种base,虽然不是通过继承).

struct foo_t {};
struct derived : decorator
{
  using decorator::fun; // I want "native" fun, and decorated fun.
  void fun(const foo_t&) {}
};

int main()
{
  derived d; …
Run Code Online (Sandbox Code Playgroud)

c++ auto return-type-deduction c++14

24
推荐指数
1
解决办法
1339
查看次数

"使用已删除的函数"错误与std :: atomic_int

我想使用std::atomic_int变量.在我的代码中,我有:

#include <atomic>

std::atomic_int stop = 0;

int main()
{
    // Do something
}
Run Code Online (Sandbox Code Playgroud)

这给了我一个编译错误:

use of deleted function 'std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]'
 std::atomic_int stop = 0;
                        ^
Run Code Online (Sandbox Code Playgroud)

对于发生了什么有什么想法?

c++ c++11 stdatomic

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

在列表初始化中缩小转换为bool - 奇怪的行为

考虑一下这段C++ 11代码:

#include <iostream>

struct X
{
    X(bool arg) { std::cout << arg << '\n'; }
};

int main() 
{
    double d = 7.0;
    X x{d};
}
Run Code Online (Sandbox Code Playgroud)

在初始化过程中,从double到bool的转换范围正在缩小x.根据我对标准的理解,这是错误的代码,我们应该看到一些诊断.

Visual C++ 2013发出错误:

error C2398: Element '1': conversion from 'double' to 'bool' requires a narrowing conversion
Run Code Online (Sandbox Code Playgroud)

但是,Clang 3.5.0和GCC 4.9.1都使用以下选项

-Wall -Wextra -std=c++11 -pedantic 
Run Code Online (Sandbox Code Playgroud)

编译此代码没有错误,也没有警告.运行程序输出1(不出意外).


现在,让我们深入到陌生的领域.

改变X(bool arg)X(int arg)和,突然间,我们从锵得到一个错误

error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会发出警告

warning: …
Run Code Online (Sandbox Code Playgroud)

c++ standards-compliance narrowing c++11 list-initialization

24
推荐指数
1
解决办法
2245
查看次数

通用函数的重载是否可以为其他重载打开?

我想实现一些通用算法,我有很多想法,如何根据算法使用的实体的某些特征来实现专门的算法.但是,似乎我没有提出所有特殊特性,我想实现通用版本,以便它们可以与另一个专用版本一起使用.

例如,考虑distance(begin, end)(是的,我知道它在标准库中;但是,它很好很简单,可以用来演示我的问题).一般版本可能看起来像这样(我正在使用std::ptrdiff_t而不是std::iterator_traits<It>::difference_type另一种简化):

template <typename It>
auto distance(It it, It end) -> std::ptrdiff_t {
    std::ptrdiff_t size{};
    while (it != end) {
        ++it;
        ++size;
    }
    return size;
}
Run Code Online (Sandbox Code Playgroud)

当然,如果迭代器类型是随机访问迭代器,那么使用两个迭代器之间的差异来实现算法要好得多.天真地加入

template <typename It>
auto distance(It begin, It end)
     -> typename std::enable_if<is_random_access_v<It>, std::ptrdiff_t>::type {
    return end - begin;
}
Run Code Online (Sandbox Code Playgroud)

并不是很有效:两个实现对于随机访问迭代器都是同样好的匹配,即编译器认为它们是不明确的.处理这种情况的简单方法是将一般实现更改为仅适用于非随机访问迭代器.也就是说,SFINAE的选择使得它们相互排斥,同时也覆盖整个空间.

不幸的是,这组实现仍然是关闭的:至少在没有改变签名的情况下,我不能添加另一个实现,以防我对利用特殊属性的泛型实现有另一个想法.例如,如果我想为分段范围添加特殊处理(想法:当基础序列按原样由段组成时,例如,std::deque<...>或者std::istreambuf_iterator<cT>单独处理段的情况),则有必要将一般实现更改为仅适用当序列不是随机访问且它不是分段序列时.当然,如果我控制可以完成的实现.用户将无法扩展通用实现集.

我知道可以为特殊迭代器类型重载函数.但是,这将要求每次添加具有特殊功能的迭代器时,都需要实现相应的功能.目标是允许添加通用实现,这些实现是在它们被使用的实体暴露额外设施的情况下改进的.它类似于不同的迭代器类别,尽管属性与迭代器类别正交.

因此,我的问题是:

  • 可以实现通用算法,以便可以在不改变现有实现的情况下添加新的改进构思,如果是这样,如何实现?
  • 可选的后续行动(我主要对上面的问题感兴趣,但这也可能很有趣):如果不可能,这个能力是否会添加概念?

c++ templates generic-programming c++11 c++14

24
推荐指数
2
解决办法
406
查看次数

用于定义数字的数字常量之前的预期非限定id

我是C++的新手,所以我不知道他们在phidget-code示例中对这个错误的含义是什么:

Main.cpp:8:16:错误:数字常量之前的预期unqualified-id

//verander de volgende informatie naar de informatie voor jouw database

#define dserver "oege.ie.hva.nl"
#define duser "username"
#define dpassword "password"
#define ddatabase "databasename"

#define homeid 1234 //line 8
Run Code Online (Sandbox Code Playgroud)

有语法错误吗?或者是其他东西?我使用#define而不是int.

编辑:添加完整的错误日志..

完整的错误日志:http://pastebin.com/3vtbzmXD

完整的main.cpp代码:http://pastebin.com/SDTz8vni

c++ syntax c-preprocessor

24
推荐指数
2
解决办法
7万
查看次数

为什么运算符""隐藏在命名空间中?

为了你的使用operator""sstd::string必须这样做using namespace std::string_literals.但是不_保留用户定义的文字是保留的,因此可能的冲突不能成为借口.另一个operator""s来自std::chrono但是那是int文字,所以也没有冲突.

这是什么原因?

c++ c++14

24
推荐指数
1
解决办法
1640
查看次数

C++ 1z为什么不删除有向图和三字母?

C++ 1z将删除trigraphs.IBM严重反对这一点(此处此处),因此似乎存在删除/不删除双方的争论.

但既然决定删除三角形,为什么要留下有向图?我认为没有任何理由可以保留有关三角形的原因(这显然不足以保留三角形).

c++ standards digraphs trigraphs c++17

24
推荐指数
1
解决办法
2379
查看次数

删除器类型在unique_ptr与shared_ptr中

当我发现标准定义std::unique_ptr并且std::shared_ptr以两种完全不同的方式关于指针可能拥有的Deleter时,我认为这很奇怪.这是来自cppreference :: unique_ptrcppreference :: shared_ptr的声明:

template<
    class T,
    class Deleter = std::default_delete<T>
> class unique_ptr;

template< class T > class shared_ptr;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,unique_ptr将"Deleter"对象的类型"保存"为模板参数.这也可以通过稍后从指针中检索Deleter的方式看出:

// unique_ptr has a member function to retrieve the Deleter
template<
    class T,
    class Deleter = std::default_delete<T>
>
Deleter& unique_ptr<T, Deleter>::get_deleter();

// For shared_ptr this is not a member function
template<class Deleter, class T>
Deleter* get_deleter(const std::shared_ptr<T>& p);
Run Code Online (Sandbox Code Playgroud)

有人可以解释这种差异背后的理性吗?我明显赞成这个概念,unique_ptr为什么这不适用于此shared_ptr?另外,为什么get_deleter在后一种情况下会成为非成员函数呢?

c++ shared-ptr unique-ptr c++11

24
推荐指数
1
解决办法
3755
查看次数