例如,我想有型auto
的变量,因为我不知道它是什么类型。
当我尝试声明它的类/结构声明它给我这个错误:
不能推导出自动型。需要初始化
是否有办法解决它?
struct Timer {
auto start;
};
你可以,但你必须声明它static
和const
:
struct Timer {
static const auto start = 0;
};
有了这个限制,因此你不能有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)};
}
这就是C++ draft standard不得不说的使用auto
成员变量,在部分7.1.6.4 auto specifier
款4
:
自动类型说明符也可以声明在一个选择语句(6.4)或循环语句(6.5)的状态的变量使用的,在新型-ID或类型-ID类型说明符-SEQ一个新的表达式(5.3.4)中,在用于工作范围变换声明,并在声明静态数据成员具有一个类定义的成员说明书内出现大括号或-等于初始值设定(9.4.2) 。
因为它必须被初始化,这也意味着它必须是const
。因此,像下面的工作:
struct Timer
{
const static int start = 1;
};
我不认为让你太多,但。使用模板马克的建议,或现在,我想它更多一些,也许你只需要一个variant type。在这种情况下,你应该检查出Boost.Variant
或Boost.Any
。
号每个构造可以有它自己的start
初始化,所以不可能有一致的类型使用。
如果你有一个可用的表达,你可以使用:
struct Timer {
Foo getAFoo();
delctype(Timer().getAFoo().Bar()) start;
Timer() : start(getAFoo().Bar()) { /***/ }
};
间接的,前提是你不引用类的成员。
这也可以通过现在扣除引导来实现,这些简单介绍了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>>;
这可以被用来以类似的方式自动推断出类成员类型。虽然成员变量需要依赖某种方式在构造函数的参数。