我希望能够内省一个C++类的名称,内容(即成员及其类型)等.我在这里说的是原生C++,而不是托管C++,它有反射.我意识到C++使用RTTI提供一些有限的信息.哪些额外的库(或其他技术)可以提供此信息?
为什么std::make_unique标准C++ 11库中没有函数模板?我发现
std::unique_ptr<SomeUserDefinedType> p(new SomeUserDefinedType(1, 2, 3));
Run Code Online (Sandbox Code Playgroud)
有点冗长.以下不是更好吗?
auto p = std::make_unique<SomeUserDefinedType>(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
这隐藏得new很好,只提到一次类型.
无论如何,这是我尝试实现make_unique:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)
我花了很std::forward长时间来编译这些东西,但我不确定它是否正确.是吗?究竟是什么std::forward<Args>(args)...意思?编译器对此做了什么?
我的编译器不支持make_unique.怎么写一个?
template< class T, class... Args > unique_ptr<T> make_unique( Args&&... args );
Run Code Online (Sandbox Code Playgroud) 我试图创建和使用make_unique的std::unique_ptr,以同样的方式std::make_shared对存在std::shared_ptr 这里描述.Herb Sutter 提到了可能的实现make_unique,如下所示:
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}
Run Code Online (Sandbox Code Playgroud)
它似乎对我不起作用.我正在使用以下示例程序:
// testproject.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <iostream>
#include <memory>
#include <utility>
struct A {
A(int&& n) { std::cout << "rvalue overload, n=" << n << "\n"; }
A(int& n) { std::cout << "lvalue overload, n=" << n << …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一组函数模板,可以使用不同类型和数量的参数,如下所示:
template <T0>
void call(T0 arg0);
template <T0, T1>
void call(T0 arg0, T1 arg1);
template <T0, T1, T2>
void call(T0 arg0, T1 arg1, T2 arg2);
template <T0, T1, T2, T3>
void call(T0 arg0, T1 arg1, T2 arg2, T3 arg3);
template <T0, T1, T2, T3, T4>
void call(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4);
[...]
Run Code Online (Sandbox Code Playgroud)
函数内的参数都被视为相同(作为单参数模板函数的参数).这是一个库,所以我可以接受额外的努力,如果这意味着更少的工作量或更愉快的库用户界面.
我不得不为不同的项目多次这样做,而且我非常厌倦必须手动手动编写所有这些项目.当我事先不知道使用该库的项目所需的最大参数数量时,情况会变得更糟.
在我开始编写Python脚本以生成所有重载之前,是否有一些元编程方法让编译器为我做这件事?
我终于开始将我的代码库迁移到C++ 11,这导致代码更短更好.
然而,我发现当我使用新指针调用函数时,它比以前要长得多:
void addCallback(Callback*); // Takes ownership of callback.
// ...
addCallback(new Callback); // Clear.
Run Code Online (Sandbox Code Playgroud)
变
void addCallback(std::unique_ptr<Callback>); // No comment needed now!
// ...
addCallback(std::move(std::unique_ptr<Callback>(new Callback))); // bleh.
Run Code Online (Sandbox Code Playgroud)
建议的make_unique()模板功能只会稍微改善这一点.
经过一些实验,我刚刚为此编写了一个辅助模板函数:
template <typename T>
auto move_ptr(T *t) -> decltype(std::move(std::unique_ptr<T>(t))) {
return std::move(std::unique_ptr<T>(t));
}
// ..
addCallback(move_ptr(new Callback)); // Not bad!
Run Code Online (Sandbox Code Playgroud)
它似乎工作得很好 - 但我肯定在重新发明轮子?(如果我不是 - 是否有任何陷阱或可能的错误与我move_ptr或其他任何我最终称呼它?)
隐藏unique_ptr丑陋的以下"技巧"有什么问题?
class Drawable;
typedef unique_ptr<Drawable> pDrawable;
#define newDrawable(...) pDrawable(new Drawable (##__VA_ARGS__))
Run Code Online (Sandbox Code Playgroud)
前两个很好.但第三个是在VS2012中导致错误:
23 IntelliSense: "std::unique_ptr<_Ty, _Dx>::unique_ptr(const std::unique_ptr<_Ty, _Dx>::
_Myt &) [with _Ty=Drawable, _Dx=std::default_delete<Drawable>]" (declared at line 1447 of
"C:\vs2012\VC\include\memory") is inaccessible file.h 36 26
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这不会起作用,除非我误解了C++如何定义宏的工作原理.我以为它只会替换这段代码:
newDrawable(a, b, c)
Run Code Online (Sandbox Code Playgroud)
同
unique_ptr<Drawable>(new Drawable(a, b, c));
Run Code Online (Sandbox Code Playgroud)
我知道unique_ptr无法复制,但我不是在复制它.我呢?
编辑:
我收到了一些关于"使用"宏的请求:
如果我是用它,它会被使用如下:
pDrawable myDraw = newDrawable();
Run Code Online (Sandbox Code Playgroud)
我想翻译成:
unique_ptr<Drawable> myDraw = unique_ptr<Drawable>(new Drawable());
Run Code Online (Sandbox Code Playgroud)
但是,如果没有visual studio给出以下错误,我甚至无法编译宏.就好像#define中的某些内容本身是不允许的.在我进行定义的行上返回错误,而不是在我调用define的地方.
请参阅此处了解make_unique无效的原因:make_unique无法编译
EDIT2
我已经回答了下面的问题.上面的代码确实可以编译和工作.