C ++能否以某种方式接受使用' auto'?:
class A {
public:
A(): m_member(new auto)
{
[...]
}
private:
BoringToTypeType *m_member;
}
目的是利用' auto'通过简化A&#39构造函数中的成员元素初始化。实际上,代码引发了以下错误:
new expression for type 'auto' requires a constructor argument.
答案 0 :(得分:7)
new auto(...)
从(...)
内传递的表达式中推导出结果指针的类型。在您的特定情况下,没有什么可以推断出来。
您有几个选择:
m_member(new auto(x))
,其中x
是BoringToTypeType
类型的表达。
m_member(new std::remove_pointer_t<decltype(m_member)>)
,这肯定不是对BoringToTypeType
的改进。
如果您不介意定义其他辅助功能,可以选择以下方法:
template <typename T, typename... TArgs>
auto newer(T*, TArgs&&... args)
{
return new T(std::forward<TArgs>(args)...);
}
class A
{
public:
A(): m_member(newer(m_member, 12))
{
}
private:
int *m_member;
};
在这种情况下,T
纯粹用于类型推导。 m_member
必须重复两次,但是你要避免以这种方式输入它的类型。
Simple tests on godbolt.org表明newer
不会产生任何额外开销。
答案 1 :(得分:6)
如果您不想重复该类型名称,可以添加私人别名:
class A {
using mem_t = BoringToTypeType;
public:
A(): m_member(new mem_t)
{
[...]
}
private:
mem_t *m_member;
}
当然,在实际代码中,在大多数情况下,您应该使用std::unique_ptr
或类似代码而不是原始指针。
答案 2 :(得分:0)
您可以定义自动构造函数类 - 在将指针转换为此对象时需要创建新对象的想法(working demo):
首先是这个自动构造函数(或者任何构造函数)类:
#include <tuple>
#include <utility>
template <typename ...T>
class AutoConstructor
{
public:
template <typename ...U>
AutoConstructor(U&&... a) : params(std::forward<U>(a)...) {}
template <typename U>
operator U* ()
{
return construct<U>(std::index_sequence_for<T...>{});
}
private:
template <typename U, std::size_t ...I>
U* construct(std::index_sequence<I...>)
{
return new U(std::forward<T>(std::get<I>(params))...);
}
std::tuple<T...> params;
};
很难使用这个没有辅助函数的类函数:
template <typename ...T>
auto makeAuto(T&&... a)
{
return AutoConstructor<T...>(std::forward<T>(a)...);
}
然后 - 这样的“魔力”是可能的:
long&& d = 7;
int* a = makeAuto();
S *s = makeAuto(std::ref(*a), 2, std::make_unique<float>(3), std::move(d));
假设S有c-tor S(int& a, const int& b, std::unique_ptr<float> c, long d)
总结一下 - 我提供的这段代码很容易使用 - 但我怀疑在代码makeAuto
调用中随处可能是个好习惯...
答案 3 :(得分:-1)
将m_member设为std::unique_ptr
,即可访问element_type
。所以代码看起来像:
class A {
public:
A(): m_member(std::make_unique<decltype(m_member)::element_type>(...))
{
[...]
}
private:
std::unique_ptr<BoringToTypeType> m_member;
};
这是否有所改善是值得商榷的 - 但如果BoringToTypeType
更复杂,这会有所帮助。