Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #86832

Re: Is this valid C++ code?

From Andrey Tarasevich <andreytarasevich@hotmail.com>
Newsgroups comp.lang.c++
Subject Re: Is this valid C++ code?
Date 2022-10-07 12:41 -0700
Organization A noiseless patient Spider
Message-ID <thpvdl$3qfkl$2@dont-email.me> (permalink)
References <bc46c146-abb5-4b16-b62d-324e049c7083n@googlegroups.com>

Show all headers | View raw


On 10/3/2022 2:09 PM, daniel...@gmail.com wrote:
> Hello everyone,
> 
> Is the C++ code below valid?
> 
> #include <iostream>
> #include <string_view>
> #include <string>
> 
> template <class T, class Enable = void>
> class Foo
> {};
> 
> template <class T>
> class Foo<T,typename std::enable_if<std::is_same<T,std::string>::value>::type>
> {
> public:
>      
>      void f(std::string s)
>      {
>          Foo<std::string_view> foo; // (*)
>          foo.f(s);
>      }
> };
> 
> template <class T>
> class Foo<T, typename std::enable_if<std::is_same<T, std::string_view>::value>::type>
> {
> public:
>      
>      void f(std::string_view s)
>      {
>          std::cout << s << "\n";
>      }
> };
> 
> int main()
> {
>      Foo<std::string> foo;
>      foo.f("Hello World");
> }
> 
> LLVM (clang-cl) says "yes", and outputs "Hello World".
> 
> Visual Studio 2022 (v143) says "no", "'f': is not a member of 'Foo<std::basic_string_view<char,std::char_traits<char>>,void>",		17	
> at line (*)
> 
> Both compiled with C++17.
> 

Your program is invalid (ill-formed). However, no diagnostic is required.

An issue of the same general nature can be demonstrated by a more simple 
example

   class C;

   template <typename T = int> void foo() {
     C c;  // Incomplete type error? Or not?
   }

   int main() {
     foo();
   }

   class C {};

Note that the above code is also quietly accepted by GCC, but rejected 
by MSVC and Clang.

Briefly and informally, the rule it violates says the following: if the 
interpretation of your template changes depending on its point of 
instantiation, the program is ill-formed. In a more focused and formal 
form: if a reference to an non-dependent name from an imaginary 
instantiation that immediately follows the definition is invalid, the 
program is ill-formed.

A complete set of formal requirements can be found in [temp.res]:

   https://timsong-cpp.github.io/cppwp/n4659/temp.res#8.3
   https://timsong-cpp.github.io/cppwp/n4659/temp.res#8.4
   https://timsong-cpp.github.io/cppwp/n4659/temp.res#temp.point-8

The first two links deal with non-dependent names, while the third one 
applies to dependent names. But the general idea is the same: if the 
meaning of a template specialization depends on its point of 
instantiation, the program is ill-formed. If the meaning of a template 
specialization changes as you move it up and down in the translation 
unit, the program is ill-formed. Yet, no diagnostic is required.

This is basically it.

But there's another detail at play here. The freedom provided by "no 
diagnostic is required" supplies the implementations with quite a bit of 
leeway in choosing the point of instantiation. The obvious next logical 
step is the resolution of DR#993

   https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#993

It allows implementations to stop worrying about choosing the proper 
point of instantiation completely. It allows them to simply push all 
instantiations to the very end of the translation unit and be done with it.

This is an opportunity GCC immediately took advantage of. GCC 
instantiates templates at the very end of the TU and, expectedly, 
interprets their content from that vantage point. Which is why GCC 
reports errors neither in your example nor in mine. Meanwhile, Clang and 
MSVC still stick to the "early instantiation" approach, which allows 
them to see the problems in our examples.

-- 
Best regards,
Andrey

Back to comp.lang.c++ | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

Is this valid C++ code? "daniel...@gmail.com" <danielaparker@gmail.com> - 2022-10-03 14:09 -0700
  Re: Is this valid C++ code? David LaRue <huey.dll@tampabay.rr.com> - 2022-10-03 23:52 +0000
    Re: Is this valid C++ code? "daniel...@gmail.com" <danielaparker@gmail.com> - 2022-10-03 18:07 -0700
      Re: Is this valid C++ code? "daniel...@gmail.com" <danielaparker@gmail.com> - 2022-10-03 18:42 -0700
    Re: Is this valid C++ code? Juha Nieminen <nospam@thanks.invalid> - 2022-10-04 06:05 +0000
  Re: Is this valid C++ code? Bo Persson <bo@bo-persson.se> - 2022-10-04 13:47 +0200
    Re: Is this valid C++ code? "daniel...@gmail.com" <danielaparker@gmail.com> - 2022-10-04 05:22 -0700
    Re: Is this valid C++ code? Manfred <noname@add.invalid> - 2022-10-05 02:54 +0200
  Re: Is this valid C++ code? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-10-07 12:41 -0700
    Re: Is this valid C++ code? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-10-08 11:18 -0700

csiph-web