Auto assignment confusion with list initialization syntax
I am only now able to use C ++ 11 for the first time at my job and I am learning as I go. I've read GotW # 94 and I'm trying to accept its recommendation for using auto
local variables instead of explicitly specifying the type.
With that in mind, I have the following code:
class foo
{
};
int main()
{
auto f = foo const*{nullptr};
}
My assignment is mostly not compiled and executed with:
main.cpp: In function 'int main()':
main.cpp:13:18: error: expected primary-expression before 'const'
auto f = foo const*{nullptr};
^
I feel like I am missing something obvious. What am I doing wrong here?
(My sample is at coliru ).
source to share
When you use functional notation for type conversion, the type name must be a simple type specifier or a type specifier (§5.2.3 [expr.type.conv]), which basically means a one-word type name.
unsigned int a = unsigned int(42);
doesn't work either, and it doesn't use type initialization or list initialization.
In my opinion, the usage auto
in your example comes down to obfuscation. Just use
foo const* f{nullptr};
If you must use auto
, create an alias
using foo_const_p = foo const*;
auto f = foo_const_p{nullptr};
source to share
Syntax T(x)
and T{x}
does not allow arbitrary types for T
. If you allow this, the syntax is quite complex in some cases. If you really want to use auto
here, you will need to wrap the type, for example:
template <typename T> using id = T;
auto f = id<foo const*>{nullptr};
but personally I don't really find it useful here.
More specifically, C ++ syntax defines grammatical constructs as
postfix-expression : ... simple-type-specifier ( expression-listopt ) ... simple-type-specifier braced-init-list ... simple-type-specifier : ::optnested-name-specifieropttype-name ::optnested-name-specifier template simple-template-id char char16_t char32_t wchar_t bool short int long signed unsigned float double void auto decltype-specifier type-name : class-name enum-name typedef-name simple-template-id
The syntax for resolving arbitrary types is part of a rule type-id
, which is not an option simple-type-specifier
, but is one option for a rule template-argument
within simple-template-id
, which is why a template alias is a valid workaround.
source to share