为什么编译器不能从 std::make_shared 中推导出模板参数?
Why the compiler cannot deduce the template arguments from std::make_shared?
我在“C++ 入门,第 5 版”中的练习中遇到了这个简单的问题:
Exercise 16.38: When we call make_shared (§ 12.1.1, p. 451), we have to provide an explicit template argument. Explain why that argument is needed and how it is used.
我试过了,看到了一些答案和建议,但我还没有被说服。
有人说:
The argument is probably need for the return type which cannot be deduced from the arguments supplied in the function call (i.e. make_shared<int>
returns a shared_ptr<int>
).
Alternatively the function body of make_shared
needs to know what type to allocate to dynamic memory which is not deducible from the arguments supplied.
但我自己试过这段代码:
template <typename T>
std::vector<T> make_vec(T x...)
{
return std::vector<T>(x);
}
int main()
{
auto vi = make_vec(77);
std::cout << vi.size() << std::endl;
}
如您所见,我的 make_vec
可以在没有显式模板参数的情况下工作,而 make_shared()
则不能。这是为什么?
std::make_shared
长得像
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
之所以需要提供 T
是因为无法从 Args
知道要创建什么类型的对象。假设你有
struct Foo1
{
Foo1(int, int) {}
};
struct Foo2
{
Foo2(int, int) {}
};
然后你做
auto foo_ptr = std::make_shared(42, 42);
无法知道您应该创建 Foo1
还是 Foo2
,因此您需要提供要创建的对象类型。
对于 std::make_shared
的大多数变体,其中 return 是 std::shared_ptr<T>
或 std::shared_ptr<U[]>
- 没有参数具有类型 T
。示例:
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
template<class T>
shared_ptr<T> make_shared( std::size_t N );
(在后一个例子中,对于某些 U
,T
必须是 U[]
)。
如果这些函数没有类型 T
参数 - 你怎么能推导出 T
(或 U
)?
在你的例子中,你做接受类型T
的参数并且可以很容易地推导出模板参数。
我在“C++ 入门,第 5 版”中的练习中遇到了这个简单的问题:
Exercise 16.38: When we call make_shared (§ 12.1.1, p. 451), we have to provide an explicit template argument. Explain why that argument is needed and how it is used.
我试过了,看到了一些答案和建议,但我还没有被说服。
有人说:
The argument is probably need for the return type which cannot be deduced from the arguments supplied in the function call (i.e.
make_shared<int>
returns ashared_ptr<int>
).Alternatively the function body of
make_shared
needs to know what type to allocate to dynamic memory which is not deducible from the arguments supplied.
但我自己试过这段代码:
template <typename T>
std::vector<T> make_vec(T x...)
{
return std::vector<T>(x);
}
int main()
{
auto vi = make_vec(77);
std::cout << vi.size() << std::endl;
}
如您所见,我的 make_vec
可以在没有显式模板参数的情况下工作,而 make_shared()
则不能。这是为什么?
std::make_shared
长得像
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
之所以需要提供 T
是因为无法从 Args
知道要创建什么类型的对象。假设你有
struct Foo1
{
Foo1(int, int) {}
};
struct Foo2
{
Foo2(int, int) {}
};
然后你做
auto foo_ptr = std::make_shared(42, 42);
无法知道您应该创建 Foo1
还是 Foo2
,因此您需要提供要创建的对象类型。
对于 std::make_shared
的大多数变体,其中 return 是 std::shared_ptr<T>
或 std::shared_ptr<U[]>
- 没有参数具有类型 T
。示例:
template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );
template<class T>
shared_ptr<T> make_shared( std::size_t N );
(在后一个例子中,对于某些 U
,T
必须是 U[]
)。
如果这些函数没有类型 T
参数 - 你怎么能推导出 T
(或 U
)?
在你的例子中,你做接受类型T
的参数并且可以很容易地推导出模板参数。