C++ 模板别名shared_ptr和unique_ptr时是否存在任何缺陷或限制?

C++ 模板别名shared_ptr和unique_ptr时是否存在任何缺陷或限制?,c++,c++11,smart-pointers,using-directives,C++,C++11,Smart Pointers,Using Directives,原因很简单,可以减少打字,比如: std::shared_ptr<...>; std::unique_ptr<...>; std::shared\u ptr; std::唯一的ptr; 每次我想使用智能指针时,我都会考虑使用模板别名: template <typename T> using sptr = std::shared_ptr<T>; template <typename T> using uptr = std::uniqu

原因很简单,可以减少打字,比如:

std::shared_ptr<...>;
std::unique_ptr<...>;
std::shared\u ptr;
std::唯一的ptr;
每次我想使用智能指针时,我都会考虑使用模板别名:

template <typename T> using sptr = std::shared_ptr<T>;
template <typename T> using uptr = std::unique_ptr<T>;
使用sptr=std::shared\u ptr的模板;
模板使用uptr=std::unique\u ptr;
所以我可以像这样使用它们:

sptr<...>;
uptr<...>;
sptr;
uptr;

假设我在自己的命名空间中保护它们,那么以这种方式将模板别名与shared/unique_ptr一起使用是否存在任何缺陷或限制?我会不会永远无法用直接模板语法做一些别名做不到的事情?出于其他原因,这是一个坏主意吗?

这很好,不会对代码产生不可预见的后果

在您的示例中,
std::unique\u ptr
std::shared\u ptr
将与
uptr
sptr
相同。您甚至可以使用静态断言来验证这一点:

static_assert(std::is_same<std::shared_ptr<T>, sptr<T>>::value, "");
static_断言(std::is_same::value,”);
使用别名声明被认为是完全相同的类型。不仅“相似”,而且完全相同。这就是为什么可以继续这样做,而不必担心以后的任何后果

别名声明将来唯一会限制的是将其他参数传递给类型以外的智能指针的能力,例如,
std::unique_ptr
可以接受删除器。如果愿意,可以修改using声明,使其包含一个更完整的定义和一个可选的deleter参数,尽管我希望大多数人永远不会使用这个特性

另一方面,需要记住的另一件事是,还有谁会阅读您的代码<代码>std::shared_ptr很清楚,很明显,但是
sptr
不太清楚。或者更确切地说,也许不是“不太清楚”,但它需要被理解。它为坐下来查看代码的人增加了一个减速带,因为他们需要在内部将
uptr
sptr
转换为
unique\ptr
shared\ptr

引用标准(7.1.3)

使用typedef说明符声明的名称将成为typedef名称。 在其声明的范围内,typedef名称在语法上是 相当于关键字,并命名与 第8条所述方式的标识符因此,typedef名称是 另一种类型的同义词。typedef名称不会引入新类型 类声明(9.1)或枚举声明的方式

别名声明也可以引入typedef名称。这个 using关键字后面的标识符将成为typedef名称和 标识符后的可选属性说明符seq 与该typedef名称对应。它的语义与 由typedef说明符引入。特别是,它没有定义 新类型,且不应出现在类型id中


答案已经给出了,在您的情况下,答案将是相同的,但模板别名有时可能会引入新名称,下面是一个示例

#include <type_traits>

template <typename T> class A {};
template <typename T> using B = A<T>;

template < template <typename T> class S> class C {};

static_assert( std::is_same< A<int>, B<int> >::value, "same :)"); // they are the same
static_assert( std::is_same< C<A>, C<B> >::value, "not the same :("); // error, not the same
#包括
模板类A{};
使用B=A的模板;
模板<模板类S>类C{};
静态断言(std::is_same::值,“same:)”);//它们是一样的
静态断言(std::is_same::值,“不相同:(“”;//错误,不相同

在这里,即使
A
B
是相同的,
C
C
是不同的。

不要这样做。
是的,你当然可以这样做,但是你应该这样做吗?IHMO,这会降低你的代码的可读性,因为每个人都知道什么是
std::unique_ptr
,但是除了编写奇怪代码的人之外,没有人知道什么是
uptr

易于维护的代码易于阅读,使用类型和值的名称来表达其目的和意图,因此只需要很少的注释(避免注释,因为它们很难维护)。使用较短的
uptr
,您将离开这条智慧之路



当然,您可以使用更具描述性的名称,例如
unique\u pointer
(在注释中建议),并使用typedefs通过
std::unique\u ptr
或(如果不可用)boost::unique\u ptr(虽然如果你没有
std::unique\u ptr
,我会认为你也没有移动语义,因此
unique\u指针的全部意义都丢失了)。但是这将无助于你减少打字。

对于
std::shared\u ptr“是的,你当然可以这样做,但你应该这样做吗?”你只给出了拒绝的理由,这是一个不平衡的论点。@MichaelGazonda一个不平衡的论点--真是胡说八道!没有什么好的理由。因此没有什么可以平衡我的论点。@Walter Well用一个更好的名字(比如更详细的
唯一的\u指针
),我看不出有什么害处。事实上有一个好处:不支持
std::unique_ptr
的库版本是真实存在的。因此,一个简单的编译时开关允许
unique_指针
变为
boost::unique_ptr
。用户实际上不需要知道它是哪个实现,只要它的行为像“OpjyPosixPosith<代码>。OP希望避免键入。用<代码> UNQuijyPosie你没有达到这个目标。@沃尔特减少打字和减少冗长是两个不同的事情。第二个比你选择的要有意义。但是也许在C++中,年轻人必须把事实告诉一个指针。在一个代码行上取1个字符,而拥有一个指针在屏幕空间上占据15个字符是非常愚蠢的。简洁在语言中也是重要的,而不仅仅是为了省略一些打字。是的,我在批评C++。
template <typename T>
using sptr = std::shared_ptr<T>;
std::unique_ptr<FILE, void (*)(FILE*)> file(fopen("myfile.txt", "r"), [](FILE* f)
                                                                      {
                                                                         fclose(f);
                                                                      });
// use file here to perform input operations
// automatic call to fclose at the end of scope (or any scope exit)