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 ).

+3


source to share


2 answers


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};

      

+4


source


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.

+1


source







All Articles