C++ 是否可以有一个“自动”成员变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18199728/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to have an "auto" member variable?
提问by Oleksiy
For example I wanted to have a variable of type auto
because I'm not sure what type it will be.
例如,我想要一个类型的变量,auto
因为我不确定它将是什么类型。
When I try to declare it in class/struct declaration it's giving me this error:
当我尝试在类/结构声明中声明它时,它给了我这个错误:
Cannot deduce auto type. Initializer required
无法推断自动类型。需要初始化程序
Is there a way around it?
有办法解决吗?
struct Timer {
auto start;
};
回答by Mark Garcia
You can, but you have to declare it static
and const
:
你可以,但你必须声明它static
并且const
:
struct Timer {
static const auto start = 0;
};
With this limitation, you therefore cannot have start
as a non-static member, and cannot have different values in different objects.
由于此限制,因此您不能将其start
作为非静态成员,并且不能在不同的对象中具有不同的值。
If you want different types of start
for different objects, better have your class as a template
如果您想要不同start
对象的不同类型,最好将您的类作为模板
template<typename T>
struct Timer {
T start;
};
If you want to deduce the type of T
, you can make a factory-like function that does the type deduction.
如果你想推导 的类型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)};
}
回答by Shafik Yaghmour
This is what the C++ draft standardhas to say about using auto
for member variables, in section 7.1.6.4 auto specifier
paragraph 4
:
这就是C++ 草案标准关于使用auto
成员变量的说法,在章节7.1.6.4 auto specifier
段落中4
:
The auto type-specifier can also be used in declaring a variable in the condition of a selection statement (6.4) or an iteration statement (6.5), in the type-specifier-seq in the new-type-id or type-id of a new-expression (5.3.4), in a for-range-declaration, and in declaring a static data member with a brace-or-equal-initializer that appears within the member-specification of a class definition (9.4.2).
auto 类型说明符也可用于在选择语句 (6.4) 或迭代语句 (6.5) 的条件中声明变量,在 new-type-id 或 type-id 的 type-specifier-seq 中new 表达式 (5.3.4),在 for-range-declaration 中,以及在声明一个静态数据成员时,该静态数据成员出现在类定义 (9.4.2) 的成员规范中.
Since it must be initialized this also means that it must be const
. So something like the following will work:
由于它必须被初始化,这也意味着它必须是const
. 因此,类似以下内容将起作用:
struct Timer
{
const static int start = 1;
};
I don't think that gets you too much though. Using template as Mark suggests or now that I think about it some more maybe you just need a variant type. In that case you should check out Boost.Variant
or Boost.Any
.
不过,我认为这不会让你太过分。按照 Mark 的建议使用模板,或者现在我再考虑一下,也许您只需要一个变体类型。在这种情况下,您应该查看Boost.Variant
或Boost.Any
。
回答by MSalters
No. Each constructor could have its own initializer for start
, so there could be no consistent type to use.
不。每个构造函数都可以有自己的 初始化器start
,因此可能没有一致的类型可供使用。
If you dohave a usable expression, you can use that:
如果您确实有可用的表达式,则可以使用它:
struct Timer {
Foo getAFoo();
delctype(Timer().getAFoo().Bar()) start;
Timer() : start(getAFoo().Bar()) { /***/ }
};
回答by David Ledger
Indirectly, provided that you don't reference a member of the class.
间接地,前提是您不引用类的成员。
This can also now be achieved through deduction guides, these were introduced in C++17 and have recently (finally) support in VC++ has been added (clang and GCC already had it).
这现在也可以通过推导指南来实现,这些指南是在 C++17 中引入的,并且最近(最终)添加了 VC++ 支持(clang 和 GCC 已经有了它)。
https://en.cppreference.com/w/cpp/language/class_template_argument_deduction
https://en.cppreference.com/w/cpp/language/class_template_argument_deduction
For example:
例如:
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>>;
This can be used to deduce class member types in a similar manner to auto. Although the member variables need to be Dependant somehow on the constructor arguments.
这可用于以与 auto 类似的方式推断类成员类型。尽管成员变量需要以某种方式依赖于构造函数参数。