vector
(以及list
其他容器)具有成员函数(MF)assign
.我想比较assign
MF(范围版本)与赋值运算符.
据我所知,在以下情况下使用是有用的assign
:
在其他情况下,assign
MF 没有缺点,可以使用赋值运算符.我对吗?使用assign
MF 还有其他一些原因吗?
它 广泛 知道,你可以使用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) 作为一个愚蠢的例子,假设我有一个函数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)
还是有一些首选的选择?
我试图转发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) #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]定义的规范形式的转换序列,不包括任何左值转换;恒等转换序列被认为是任何非-身份转换序列),或者,如果不是,
在这两种情况下发生了什么?
在回答这个问题时(更好地阅读这个"重复"),我想出了以下解决方案来依赖运营商的名称:
[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> …
我需要在源代码中找到所有这些地方,其中隐式转换任何类型的指针void *
或停止这些隐式转换的方法.
例如:
int *
至 void *
char *
至 void *
Base *
至 void *
是否有任何gcc警告或错误标志,它会检测指针被隐式转换为的所有这些行void *
?
具有非虚拟析构函数的类如果它们被用作基类(如果使用指向基类的指针或引用来引用子类的实例),则它们是错误的来源.
随着C++ 11添加一个final
类,我想知道是否有意义设置以下规则:
每个类必须满足以下两个属性之一:
final
(如果它还没有被继承)可能有些情况下这两个选项都没有意义,但我想它们可以被视为应该仔细记录的例外情况.
考虑以下一组示例.
takeOnlyVoidFunction
采用零参数的函数并简单地执行它.takeVariableArguments
接受可变数量的参数并使用参数执行函数.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) 我正在尝试使用移动文件SetFileInformationByHandle
.Niall Douglas在他的CppCon2015谈话"赛车文件系统"中提出了这种技术,作为原子地移动/重命名文件的一种方式.但是,我很难提供正确的论据; 它总是失败并GetLastError
返回ERROR_INVALID_PARAMETER
.
我使用Unicode字符集通过以下设置尝试了这个:
但行为是一样的.我确保可以访问测试文件夹和测试文件.
#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)