title: Why won't VisualStudio let me use QStringLiteral inside a lambda if QT_NO_CAST_FROM_ASCII is defined?
body: <p>We're in the process of making our codebase encoding safe via <code>QT_NO_CAST_FROM_ASCII</code>. Everything has been working fine with gcc and clang, but under VisualStudio 2010 we have run into the following unusual compile issue.</p>
  
  <p>This code:</p>
  
  <pre><code>#define QT_NO_CAST_FROM_ASCII
  #include &lt;QString&gt;
  void func()
  {
      auto f = [] () -&gt; QString
      {
          QString a = QStringLiteral("Hello.");
          return a;
      };
      QString b = f();
  }
  </code></pre>
  
  <p>generates this error:</p>
  
  <pre><code>1&gt;example.cpp(7): error C2248: 'QString::QString' : cannot access private member declared in class 'QString'
  1&gt;          C:\Qt\5.1.1\include\QtCore/qstring.h(691) : see declaration of 'QString::QString'
  1&gt;          C:\Qt\5.1.1\include\QtCore/qstring.h(207) : see declaration of 'QString'
  </code></pre>
  
  <p>The actual constructor it's complaining about being private is <code>QString(const char *)</code>.</p>
  
  <p><code>QStringLiteral()</code> is a complex macro that does a lot of C++11 black magic, so it's not entirely surprising that an older version of VisualC++ chokes on it. The interesting thing is that the error only shows up when using <code>QStringLiteral()</code> inside of lambda when <code>QT_NO_CAST_FROM_ASCII</code> is defined!</p>
  
  <p>This compiles:</p>
  
  <pre><code>#undef QT_NO_CAST_FROM_ASCII  // Note the undef!
  #include &lt;QString&gt;
  void func()
  {
      auto f = [] () -&gt; QString
      {
          QString a = QStringLiteral("Hello.");
          return a;
      };
      QString b = f();
  }
  </code></pre>
  
  <p>As does this:</p>
  
  <pre><code>#define QT_NO_CAST_FROM_ASCII
  #include &lt;QString&gt;
  void func()
  {
      auto f = [] () -&gt; QString
      {          
          QString a = QLatin1String("Hello."); // Note using QLatin1String() instead.
          return a;
      };
      QString b = f();
  }
  </code></pre>
  
  <p>And this:</p>
  
  <pre><code>#define QT_NO_CAST_FROM_ASCII
  #include &lt;QString&gt;
  void func()
  {
      QString a = QStringLiteral("Hello."); // Note QStringLiteral() used outside the lambda.
      auto f = [&amp;a] () -&gt; QString
      {          
          return a;
      };
      QString b = f();
  }
  </code></pre>
  
  <p>What is going on? It's not a critical issue; there are plenty of workarounds available, but it's just strange enough that I can't stop wondering why.</p>
  
  <p><strong>Update:</strong></p>
  
  <p>I had looked at the <code>QStringLiteral</code> macro before posting, but at Alf's suggestion I fully expanded it, which (after formatting for clarity) gives:</p>
  
  <pre><code>#define QT_NO_CAST_FROM_ASCII
  #include &lt;QString&gt;
  void func()
  {
      auto f = [] () -&gt; QString
      {
          QString a = (   []() -&gt; QString
                          {
                              enum { Size = sizeof(L"Hello.")/2 - 1 };
                              static const QStaticStringData&lt;Size&gt; qstring_literal = { { { { (-1) } }, Size, 0, 0, sizeof(QStringData) }, L"Hello." };
                              QStringDataPtr holder = { qstring_literal.data_ptr() }; 
                              const QString s(holder);
                              return s;
                          }()
                      );
          return a;
      };
      QString b = f();
  }
  </code></pre>
  
  <p>This generates the exact same error, which now suggests that the compiler things the return type of the lambda call is <code>char *</code>, despite it explicitly having a return type of <code>QString</code>. However, making one small-ish change results in something that does compile:</p>
  
  <pre><code>#define QT_NO_CAST_FROM_ASCII
  #include &lt;QString&gt;
  void func()
  {
      auto f = [] () -&gt; QString
      {
          auto qsl =  []() -&gt; QString
                      {
                          enum { Size = sizeof(L"Hello.")/2 - 1 };
                          static const QStaticStringData&lt;Size&gt; qstring_literal = { { { { (-1) } }, Size, 0, 0, sizeof(QStringData) }, L"Hello." };
                          QStringDataPtr holder = { qstring_literal.data_ptr() }; 
                          const QString s(holder);
                          return s;
                      };
          QString a = qsl();
          return a;
      };
      QString b = f();
  }
  </code></pre>
  
  <p>So apparently attempting to call <code>operator()</code> on the lambda definition directly just confuses the compiler into doing I-don't-know-what. The crazy thing is that if <code>QT_NO_CAST_FROM_ASCII</code> isn't defined, the <code>QString(const char *)</code> constructor is no longer private and presumably the compiler somehow successfully uses it on the result of the lambda call, despite the fact that the lambda doesn't return a <code>char *</code></p>