Clang error: sorry, non-type template argument of pointer-to-member type B that refers to member A of a different class is not supported yet (err_template_arg_member_ptr_base_derived_not_supported)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: sorry, non-type template argument of pointer-to-member type B that refers to member A of a different class is not supported yet
Type Error
Category Semantic Issue
Internal Id err_template_arg_member_ptr_base_derived_not_supported
Internal Message sorry, non-type template argument of pointer-to-member type %1 that refers to member %q0 of a different class is not supported yet
Regular Expression (?:error|fatal error)\: sorry, non\-type template argument of pointer\-to\-member type (.*?) that refers to member (.*?) of a different class is not supported yet
First Commit 2014-11-26 410cc893745e [c++1z] Most of N4268 (allow constant evaluation for non-type template arguments).

Description

The error is issued by the Clang compiler when attempting to use a non-type template argument that is a pointer to a member of a class, but the specified member belongs to a different class than the one pointed at. This situation arises in C++ when templates are leveraged to achieve more generic and reusable code. Non-type template parameters can be values or objects at compile time, including pointers to members. However, C++ standards and compiler implementations place restrictions on their usage to ensure type safety and correct semantics.

C++ allows for pointer-to-member types to be used as template arguments. These types are distinct from regular pointer types in that they carry information about both the member and its class. This design is crucial for safely handling inheritance and polymorphism, allowing operations on members of possible subclasses.

When a pointer-to-member is used as a template argument, and it points to a member of a class that is not the type being instantiated by the template, it causes an inconsistency. This restriction is rooted in C++'s strong type system, emphasizing type safety and preventing operations that could lead to undefined behavior.

This error message specifically indicates that the compiler currently does not support such use cases. Despite ongoing evolution in the C++ language and its implementations, including more flexible template arguments, certain specialized uses, like the one triggering this error, remain out of scope because of complex semantics, the need for additional language support (mangling rules, for example), or simply because they are not yet implemented.

 
AI Generated

Example

In the following example, a struct named B is defined with an integer member x. Another struct named D is declared, which inherits from B. The example aims to illustrate the usage of a template S that takes non-type template parameters. These parameters are pointers to member integers from structs B and D. An attempt is made to instantiate the template S with a pointer to the member x from B as both template arguments. However, the second template argument attempts to cast &B::x to a pointer-to-member of D, which introduces the error. The Clang compiler issues the error message because it does not support a non-type template argument that refers to a member of one class being used with another class, highlighting the strict type safety enforced in C++ template arguments. This situation is complicated by the inheritance relationship between B and D, demonstrating a scenario that the current C++ standard and compiler implementation do not support due to restrictions on non-type template arguments.  
AI Generated


Flags -xc++ -std=c++17

[Try out in Compiler Explorer]

Source
struct B { int x; };

struct D : B { };

// This struct's template tries to use pointers to member of different types.
template <int B::* BP, int D::* DP> struct S { };

// Error: BP and DP are from different classes.
S<&B::x, static_cast<int D::*>(&B::x)> s;
Compiler Output
<source>:9:10: error: sorry, non-type template argument of pointer-to-member type 'int D::*' that refers to member 'B::x' of a different class is not supported yet


Clang Internals (17.0.6)

Git Commit Message

[c++1z] Most of N4268 (allow constant evaluation for non-type template arguments).

We don't yet support pointer-to-member template arguments that have undergone
pointer-to-member conversions, mostly because we don't have a mangling for them yet.

llvm-svn: 222807

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaTemplate.cpp (line 7324)

/// Check a template argument against its corresponding
/// non-type template parameter.
///
/// This routine implements the semantics of C++ [temp.arg.nontype].
/// If an error occurred, it returns ExprError(); otherwise, it
/// returns the converted template argument. \p ParamType is the
/// type of the non-type template parameter after it has been instantiated.
ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, QualType ParamType, Expr *Arg, TemplateArgument &SugaredConverted, TemplateArgument &CanonicalConverted, CheckTemplateArgumentKind CTAK) {
  // ...
  if (getLangOpts().CPlusPlus17) {
    // ...
    case APValue::MemberPointer: {
      // ...
      // FIXME: We need TemplateArgument representation and mangling for these.
      if (!Value.getMemberPointerPath().empty()) {
        Diag(Arg->getBeginLoc(), diag::err_template_arg_member_ptr_base_derived_not_supported) << Value.getMemberPointerDecl() << ParamType << Arg->getSourceRange();

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:100:28: error: sorry, non-type template argument of pointer-to-member type 'int PtrMem::B::*' that refers to member 'PtrMem::E::e' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:101:28: error: sorry, non-type template argument of pointer-to-member type 'int PtrMem::B::*' that refers to member 'PtrMem::E::e' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:105:43: error: sorry, non-type template argument of pointer-to-member type 'int PtrMem::B::*' that refers to member 'PtrMem::E::e' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:109:28: error: sorry, non-type template argument of pointer-to-member type 'int PtrMem::E::*' that refers to member 'PtrMem::B::b' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:110:28: error: sorry, non-type template argument of pointer-to-member type 'int PtrMem::E::*' that refers to member 'PtrMem::B::b' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:114:43: error: sorry, non-type template argument of pointer-to-member type 'int PtrMem::E::*' that refers to member 'PtrMem::B::b' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:208:34: error: sorry, non-type template argument of pointer-to-member type 'int Auto::Basic::Y::*' that refers to member 'Auto::Basic::X::n' of a different class is not supported yet
  • clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp:210:34: error: sorry, non-type template argument of pointer-to-member type 'const int Auto::Basic::Y::*' that refers to member 'Auto::Basic::X::n' of a different class is not supported yet