C++ 如何避免使用c++;11';创建共享\u ptr实例的s类型推断功能?

C++ 如何避免使用c++;11';创建共享\u ptr实例的s类型推断功能?,c++,c++11,type-inference,C++,C++11,Type Inference,您可以使用new c++11关键字创建一个pair实例,以完全最小化您提供给编译器的类型信息: auto my_pair(make_pair(10,"yay")); 是否有类似的机制来创建共享\u ptr?我能找到的唯一语法将类型信息重复给编译器2次: auto p = make_shared<int>(10); \ \ \ ` type information part 1

您可以使用new c++11关键字创建一个pair实例,以完全最小化您提供给编译器的类型信息:

auto my_pair(make_pair(10,"yay"));
是否有类似的机制来创建
共享\u ptr
?我能找到的唯一语法将类型信息重复给编译器2次:

auto p = make_shared<int>(10);
                       \   \
                        \   ` type information part 1
                         `duplicate type information part 2
auto p=make_shared(10);
\   \
\`类型信息第1部分
`重复类型信息第2部分
这并不比c++11之前的语法好多少

shared_ptr<int> p( new int(10) );
shared_ptr p(新整数(10));
我在想可能会有一个
make_shared_ptr
模板函数,就像有一个。
shared\u ptr
是否存在这样的模板?

(由于boost文档中提到的所有异常安全问题,我有点害怕尝试使用我自己的模板。我还想避免创建我自己的独特模板。)

你没有

传递给
make_shared
的类型没有任何意义;这还不足以知道要分配什么类型的信息。也许您想要使用某个类,它恰好将
int
作为其构造函数的参数

make_shared
不存在,因此键入
shared_ptr
构造函数更容易。它的存在有两个原因:

1:这样做会更加困难:

SomeFunc(shared_ptr<string>( new string("hi") ), shared_ptr<string>( new string("hi2") ));
SomeFunc(共享字符串(“hi”)、共享字符串(“hi2”);
< >由于C++如何定义表达式的顺序,所以在创建<代码> SyddyPt 这太可怕了

使用
make_shared
意味着不显式调用
new
。所以你不可能得到这个问题

2:它允许进行优化,其中
共享的\u ptr
控制块与相关对象的存储一起分配。执行
共享\u ptr(新字符串(“hi”)
将分配两块内存:一块用于
字符串
,另一块用于
共享\u ptr
的内部控制块。调用
make_shared(“hi”)
将只分配一个块:
字符串和内部控制块将一起分配

你所说的是一个假设的
copy\u shared
,你只需要一个参数,然后你就可以复制这个值。当然,您还需要一个
move\u shared
,它接受
&&
的值并使用move构造。

您不需要

传递给
make_shared
的类型没有任何意义;这还不足以知道要分配什么类型的信息。也许您想要使用某个类,它恰好将
int
作为其构造函数的参数

make_shared
不存在,因此键入
shared_ptr
构造函数更容易。它的存在有两个原因:

1:这样做会更加困难:

SomeFunc(shared_ptr<string>( new string("hi") ), shared_ptr<string>( new string("hi2") ));
SomeFunc(共享字符串(“hi”)、共享字符串(“hi2”);
< >由于C++如何定义表达式的顺序,所以在创建<代码> SyddyPt 这太可怕了

使用
make_shared
意味着不显式调用
new
。所以你不可能得到这个问题

2:它允许进行优化,其中
共享的\u ptr
控制块与相关对象的存储一起分配。执行
共享\u ptr(新字符串(“hi”)
将分配两块内存:一块用于
字符串
,另一块用于
共享\u ptr
的内部控制块。调用
make_shared(“hi”)
将只分配一个块:
字符串和内部控制块将一起分配


你所说的是一个假设的
copy\u shared
,你只需要一个参数,然后你就可以复制这个值。当然,您还需要一个
move\u shared
,它接受
&&
的值并使用move构造。

您发布的内容没有重复
make_shared
接受构造函数参数,这些参数不一定与
T
本身对应。即使您的示例也演示了这一点-您收到了一个
shared\u ptr
,但根本没有传递
make\u shared
a
std::string
-您传递了一个
const char(&)[N]
。这不是一个不可忽视的转换。任何特定于字符串的魔法都不会发生这种情况。它之所以发生,是因为并且仅是因为
std::string
可以在它的构造函数中使用它。我可以写很多琐碎的例子来证明这一点。向量呢

auto p = make_shared<std::vector<float>>(100); // pass 100 to vector constructor
auto p=make_shared(100);//将100传递给向量构造函数
除非您希望论证
make_shared
应该能够从
std::vector
推断出
int
作为参数,这显然是错误的,因为
std::vector
有许多其他单参数构造函数,更不用说多参数构造函数了,或者它应该能够从
int
推断
std::vector
,这显然也是错误的,因为任何
std::vector
都可以从
int
初始化,更不用说可以从
int
初始化的所有其他原语和UDT了
#include <memory>
#include <iostream>

using namespace std;

template<
        typename T,
        typename Decayed = typename std::decay<T>::type
>std::shared_ptr<Decayed> deduce_shared(T&& t){
        static_assert(!std::is_array<typename std::remove_reference<T>::type>::value, "Array parameters are not allowed.");
        return std::make_shared<Decayed>(std::forward<T>(t));
}

class Container{
        public:
                int* pricyResource = reinterpret_cast<int*>(0xBAADDEAD);

                Container(int* pricyResource):pricyResource(pricyResource){
                        cout << "Constructing, with nice resource:" << *pricyResource << endl;
                }

                Container(const Container&){
                        cout << "Copy constructing." << endl;
                }

                ~Container(){
                        cout << "Destructing." << endl;
                        delete pricyResource;
                }
};

int* acquireResource(){
        return new int(9001);
}

int main(){
        auto shared = deduce_shared(Container(acquireResource()));
        cerr << shared->pricyResource << endl;
        cerr << "Destruction / potential segfault (this case) after scope ends." << endl;
        return 0;
}
Constructing, with nice resource:9001
Copy constructing.
Destructing.
0xbaaddead
Destruction / potential segfault (this case) after scope ends.
Destructing.
Segmentation fault