是否有可能有一个“自动”成员变量?

问题描述 投票:15回答:4

例如,我想有型auto的变量,因为我不知道它是什么类型。

当我尝试声明它的类/结构声明它给我这个错误:

不能推导出自动型。需要初始化

是否有办法解决它?

struct Timer {

    auto start;

};
c++ struct auto
4个回答
24
投票

你可以,但你必须声明它staticconst

struct Timer {
    static const auto start = 0;
};

A working example in Coliru

有了这个限制,因此你不能有start作为一个非静态成员,而不能在不同的对象不同的值。

如果你想在不同种类start针对不同的对象,最好有你的类作为模板

template<typename T>
struct Timer {
    T start;
};

如果要推断T的类型,你可以做一个工厂类函数,它的类型推演。

template<typename T>
Timer<typename std::decay<T>::type> MakeTimer(T&& startVal) {   // Forwards the parameter
   return Timer<typename std::decay<T>::type>{std::forward<T>(startVal)};
}

Live example


4
投票

这就是C++ draft standard不得不说的使用auto成员变量,在部分7.1.6.4 auto specifier4

自动类型说明符也可以声明在一个选择语句(6.4)或循环语句(6.5)的状态的变量使用的,在新型-ID或类型-ID类型说明符-SEQ一个新的表达式(5.3.4)中,在用于工作范围变换声明,并在声明静态数据成员具有一个类定义的成员说明书内出现大括号或-等于初始值设定(9.4.2) 。

因为它必须被初始化,这也意味着它必须是const。因此,像下面的工作:

struct Timer
{
  const static int start = 1;
}; 

我不认为让你太多,但。使用模板马克的建议,或现在,我想它更多一些,也许你只需要一个variant type。在这种情况下,你应该检查出Boost.VariantBoost.Any


1
投票

号每个构造可以有它自己的start初始化,所以不可能有一致的类型使用。

如果你有一个可用的表达,你可以使用:

struct Timer {

   Foo getAFoo();

   delctype(Timer().getAFoo().Bar()) start;

   Timer() : start(getAFoo().Bar()) { /***/ }
};

0
投票

间接的,前提是你不引用类的成员。

这也可以通过现在扣除引导来实现,这些简单介绍了C ++ 17和最近(最终)在VC ++支持已被添加(铛和GCC已经拥有它)。

https://en.cppreference.com/w/cpp/language/class_template_argument_deduction

例如:

template <typename>
struct CString;

template <typename T, unsigned N>
struct CString<std::array<T, N>>
{
    std::array<T, N> const Label;

    CString(std::array<T, N> const & pInput) : Label(pInput) {}
};

template <typename T, std::size_t N>
CString(std::array<T, N> const & pInput) -> CString<std::array<T, N>>;

https://godbolt.org/z/LyL7UW

这可以被用来以类似的方式自动推断出类成员类型。虽然成员变量需要依赖某种方式在构造函数的参数。

© www.soinside.com 2019 - 2024. All rights reserved.