'新汽车'在C ++构造函数中

时间:2017-01-03 11:13:23

标签: c++ constructor member auto

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.

4 个答案:

答案 0 :(得分:7)

new auto(...)(...)内传递的表达式中推导出结果指针的类型。在您的特定情况下,没有什么可以推断出来。

您有几个选择:

  • m_member(new auto(x)),其中xBoringToTypeType类型的表达。

  • 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更复杂,这会有所帮助。