0

I want to define a string_view literal using the sv operator, but since my application can be compiled as either ANSI or UNICODE I use Microsoft's _T macro from tchar.h.

Since I want to apply the sv operator on a wchar_t pointer/string I assumed I had to write this:

using namespace std::literals;
constexpr static auto H1{_T("hello")sv};

But this does not compile and gives the following errors:

error C2146: syntax error: missing ')' before identifier 'sv'
error C2143: syntax error: missing ';' before '}'
error C2059: syntax error: '}'

However, when I write this, it compiles and works correctly:

using namespace std::literals;
constexpr static auto H2{_T("hello"sv)};

The first alternative seems more logical to me since the second alternative looks like the sv operator is applied on a char-pointer/string, while actually it is being applied on a Unicode string (if I compile in Unicode using the /D_UNICODE option).

Strange thing is that if I try to compile the following code:

using namespace std::literals;
constexpr static auto H1{_T("hello")sv};
constexpr static auto H2{_T("hello"sv)};
constexpr static auto H3{L"hello"sv};

then the first line does not compile, as explained above. But when I add the /EP option to the compiler (so I get a file with the output of the preprocessor), I see the preprocessor translates these lines to this:

using namespace std::literals;
constexpr static auto H1{L"hello"sv};
constexpr static auto H2{L"hello"sv};
constexpr static auto H3{L"hello"sv};

And compiling this output succeeds.

So preprocessing-only and then compiling works. Compiling in one go, doesn't.

Is there anything in the C++ standard that forbids me to use the first alternative (which seems more logical to me)? If not, is this a bug in Microsofts compiler?

Patrick
  • 23,217
  • 12
  • 67
  • 130
  • 1
    As a workaround you can use `constexpr static std::string_view H1{_T("hello")}` instead – NathanOliver Jun 24 '20 at 15:21
  • 1
    Note that data inside a macro and data outside can never combine into a single token, not even with the token-pasting operator (`##`). The file resulting from preprocessing doesn't show the token boundaries, which are different between the first and latter cases – Ben Voigt Jun 24 '20 at 15:27
  • Furthermore, consider why the definition of `_T(str)` is `L##str` and not simply `L str` – Ben Voigt Jun 24 '20 at 15:28
  • @Ben, then why does the preprocessor (using the /EP option) generate the correct, expected output, but when preprocessing-and-compiling in one go doesn't compile this? – Patrick Jun 26 '20 at 07:33
  • @Patrick: I repeat, **The file resulting from preprocessing doesn't show the token boundaries**. They are lost by writing the preprocessor result out to text and then reading it in again. – Ben Voigt Jun 26 '20 at 15:09

0 Answers0