小编dyp*_*dyp的帖子

STL - 赋值运算符与`assign`成员函数

vector(以及list其他容器)具有成员函数(MF)assign.我想比较assignMF(范围版本)与赋值运算符.

据我所知,在以下情况下使用是有用的assign:

  1. 人们想要分配向量的子范围(不是从开始到结束).
  2. 赋值是从数组完成的.

在其他情况下,assignMF 没有缺点,可以使用赋值运算符.我对吗?使用assignMF 还有其他一些原因吗?

c++ stl operators assignment-operator assign

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

shared_ptr的dtor是否需要使用"删除者"?

广泛 知道,你可以使用shared_ptr一个存储指向不完全类型,只要指针可以(有良好定义的行为)的施工过程中被删除shared_ptr.例如,PIMPL技术:

struct interface
{
    interface();                 // out-of-line definition required
    ~interface() = default;   // public inline member, even if implicitly defined
    void foo();
private:
    struct impl;                 // incomplete type
    std::shared_ptr<impl> pimpl; // pointer to incomplete type
};
Run Code Online (Sandbox Code Playgroud)

[main.cpp中]

int main()
{
    interface i;
    i.foo();
}
Run Code Online (Sandbox Code Playgroud)

[interface.cpp]

struct interface::impl
{
    void foo()
    {
        std::cout << "woof!\n";
    }
};

interface::interface()
    : pimpl( new impl ) // `delete impl` is well-formed at this point
{}

void interface::foo() …
Run Code Online (Sandbox Code Playgroud)

c++ shared-ptr language-lawyer c++11

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

使用lambda函数定义非常小的辅助函数是否很好?

作为一个愚蠢的例子,假设我有一个函数int f(vector<int> v),由于某种原因,我需要v多次执行几个操作f.而不是在其他地方放置辅助函数(这可能会增加混乱并损害可读性),做这样的事情有哪些优点和缺点(效率,可读性,可维护性等):

int f(vector<int> v)
{
    auto make_unique  = [](vector<int> &v)
    {
        sort(begin(v), end(v));
        auto unique_end = unique(begin(v), end(v));
        v.erase(unique_end, end(v));
    };
    auto print_vector = [](vector<int> const &v)
    {
        copy(begin(v), end(v), ostream_iterator<int>(cout, " "));
        cout << endl;
    };

   make_unique (v);
   print_vector(v);
   // And then the function uses these helpers a few more times to justify making
   // functions...
}
Run Code Online (Sandbox Code Playgroud)

还是有一些首选的选择?

c++ lambda coding-style c++11

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

如何转发std :: initializer_list <T>?

我试图转发std::initializer_list但是

no known conversion from 'std::initializer_list<A>' to 'std::initializer_list<B>'
Run Code Online (Sandbox Code Playgroud)

这是测试代码

#include <iostream>

class B {
};

class A: public B {
};

class not_working {
    private:
    void fun(std::initializer_list<B> p) {
    }
    public:
    template<typename T>
    not_working(std::initializer_list<T> args) {
        fun(args);
    }
};

class working {
    private:
    void fun(std::initializer_list<B> p) {
    }
    public:
    working(std::initializer_list<B> args) {
        fun(args);
    }
};

int main(){    
    working{A{}, A{}};
    //not_working{A{}, A{}};
}
Run Code Online (Sandbox Code Playgroud)

如何在std::initializer_list
没有明确演员的情况下转发not_working{(B)A{}, (B)A{}};

为什么这对我来说是个问题?

我有一个代理类,它将构造函数参数转发给一个类.像这样的东西:

 template<typename T>
 class proxy {
    T real;
    template<typename …
Run Code Online (Sandbox Code Playgroud)

c++ initializer-list c++11

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

数组到指针的转换 + rvalue-ref:重载分辨率差异 GCC vs clang

#include <iostream>
#define FUNC() { std::cout << __PRETTY_FUNCTION__ << "\n"; }

void foo(char const*&&   ) FUNC() // A
void foo(char const(&)[4]) FUNC() // B

int main()
{
    foo("bar");
}
Run Code Online (Sandbox Code Playgroud)

演示

当在第一个重载 (A) 的参数类型中使用右值引用时,clang current master 明确地选择重载 A 而不是 B。另一方面,GCC current master 抱怨歧义。

我很惊讶字符串文字是4char const左值[expr.prim.literal]/1 , [lex.string]/6)应该更喜欢重载 A 上的数组到指针转换而不是身份转换过载 B.

如果没有右值引用,即void foo(char const*),GCC 和 clang 都拒绝调用不明确。这也是我不完全理解的事情,因为我会猜测仍然存在数组到指针的转换,因此[over.ics.rank]p3.2.1适用:

  • 标准转换序列 S1 是比标准转换序列 S2 更好的转换序列,如果

    • (3.2.1) S1是S2的真子序列(比较[over.ics.scs]定义的规范形式的转换序列,不包括任何左值转换;恒等转换序列被认为是任何非-身份转换序列),或者,如果不是,

在这两种情况下发生了什么?

c++ language-lawyer overload-resolution implicit-conversion

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

从属名称解析和命名空间标准/标准库

在回答这个问题时(更好地阅读这个"重复"),我想出了以下解决方案来依赖运营商的名称:

[temp.dep.res]/1:

在解析依赖名称时,会考虑以下来源的名称:

  • 在模板定义点可见的声明.
  • 来自名称空间的声明与实例化上下文(14.6.4.1)和定义上下文中的函数参数的类型相关联.
#include <iostream>
#include <utility>

// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<int,int>& p)
{
    s >> p.first >> p.second;
    return s;
}

// include definition of `istream_iterator` only after declaring the operator
// -> temp.dep.res/1 bullet 1 applies??
#include <iterator>

#include <map>
#include <fstream>

int main()
{
    std::ifstream in("file.in");

    std::map<int, int> pp; 
    pp.insert( std::istream_iterator<std::pair<int, int>>{in},
               std::istream_iterator<std::pair<int, int>>{} );
}
Run Code Online (Sandbox Code Playgroud)

但是clang ++ 3.2和g ++ 4.8没有找到这个运算符(名称解析).

是否包含<iterator> …

c++ templates token-name-resolution c++11

6
推荐指数
1
解决办法
497
查看次数

有没有办法阻止隐式指针转换为void*

我需要在源代码中找到所有这些地方,其中隐式转换任何类型的指针void *或停止这些隐式转换的方法.

例如:

  1. int *void *
  2. char *void *
  3. Base *void *

是否有任何gcc警告或错误标志,它会检测指针被隐式转换为的所有这些行void *

c c++ pointers void-pointers implicit-conversion

6
推荐指数
1
解决办法
545
查看次数

默认为使类为"final"或给它们一个虚拟析构函数?

具有非虚拟析构函数的类如果它们被用作基类(如果使用指向基类的指针或引用来引用子类的实例),则它们是错误的来源.

随着C++ 11添加一个final类,我想知道是否有意义设置以下规则:

每个类必须满足以下两个属性之一:

  1. 被标记final(如果它还没有被继承)
  2. 有一个虚拟析构函数(如果它是(或打算)从中继承)

可能有些情况下这两个选项都没有意义,但我想它们可以被视为应该仔细记录的例外情况.

c++ final virtual-destructor c++11

6
推荐指数
2
解决办法
1455
查看次数

是否有可能在lambda中捕获可变数量的参数?

考虑以下一组示例.

  1. 该函数takeOnlyVoidFunction采用零参数的函数并简单地执行它.
  2. 该函数takeVariableArguments接受可变数量的参数并使用参数执行函数.
  3. 该函数captureVariableArgs尝试将第二个函数转换为第一个函数可接受的lambda形式,但它不能编译.

如何使函数captureVariableArgs编译并展示将具有可变数量参数的函数转换为不带参数的闭包的正确行为?

#include <stdio.h>
#include <functional>

void takeOnlyVoidFunction(std::function<void()> task) {
    task();
}

template<typename _Callable, typename... _Args>
    void takeVariableArguments(_Callable&& __f, _Args&&... __args) {
     __f(__args...);
}

// How can I make this function compile?
template<typename _Callable, typename... _Args>
    void captureVariableArgs(_Callable&& __f, _Args&&... __args) {
    takeOnlyVoidFunction([=]() { __f(__args...);});
}

void normalFunction(int a, int b) {
    printf("I am a normal function which takes params (%d,%d)\n", a, b);
}

int main() {
    int a …
Run Code Online (Sandbox Code Playgroud)

c++ lambda gcc

6
推荐指数
1
解决办法
187
查看次数

使用SetFileInformationByHandle移动文件

我正在尝试使用移动文件SetFileInformationByHandle.Niall Douglas在他的CppCon2015谈话"赛车文件系统"中提出了这种技术,作为原子地移动/重命名文件的一种方式.但是,我很难提供正确的论据; 它总是失败并GetLastError返回ERROR_INVALID_PARAMETER.

我使用Unicode字符集通过以下设置尝试了这个:

  • VS2015U1,在Windows 10下运行exe
  • VS2015U2,在Windows Server 2012下运行exe
  • VS2013,在Windows 7下运行exe

但行为是一样的.我确保可以访问测试文件夹和测试文件.

#include <sdkddkver.h>
#include <windows.h>

#include <cstring>
#include <iostream>
#include <memory>

int main()
{
    auto const& filepath = L"C:\\remove_tests\\file.txt";
    auto const& destpath = L"C:\\remove_tests\\other.txt";
    // unclear if that's the "root directory"
    auto const& rootdir = L"C:\\remove_tests";

    // handles will be leaked but that should be irrelevant here
    auto const f_handle = CreateFile(filepath,
        GENERIC_READ | GENERIC_WRITE | DELETE,
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if …
Run Code Online (Sandbox Code Playgroud)

c++ windows winapi file-rename file-move

6
推荐指数
2
解决办法
1859
查看次数