Skip to content

Template class + SFINAE member function with variadic template arguments #201

@taehyounpark

Description

@taehyounpark

This is related to #192 which was displaying the issue inside a large library + older version of cppyy used by ROOT. I've managed to isolate the issue into a minimal example on the latest version of cppyy.

Python 3.11.4 (main, Jul  5 2023, 08:41:25) [Clang 14.0.6 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cppyy
>>> cppyy.__version__
'3.0.0'

The issue seems to be stemming from the fact that cppyy cannot handle a function that is:

  1. A member function of a template class, that
  2. Accepts a template parameter pack, and
  3. Is also overloaded via SFINAE depending on the class template parameter

This (as far as I know) is valid C++ according to both GCC and Clang, including whatever is being used by the backend of cppyy. Here is the illustration of the issue:

import cppyy

cppyy.cppdef('''
template <typename T> struct TestSfinae {
  template <typename U, typename V = T,
            std::enable_if_t<std::is_arithmetic_v<V>, bool> = false>
  auto test_single(U arg) {
    std::cout << "good" << std::endl;
    return 0;
  }
  template <typename... Args, typename V = T,
            std::enable_if_t<std::is_arithmetic_v<V>, bool> = false>
  auto test_pack(Args... args) {
    std::cout << "good" << std::endl;
    return 0;
  }
};
''')

# call from cling
cppyy.cppdef('''auto testing = TestSfinae<float>();''')
cppyy.cppdef('''auto single_call = testing.test_single(1);''')  # good
cppyy.cppdef('''auto pack_call = testing.test_pack(1,2,3);''')  # good

# call from bindings
testing = cppyy.gbl.TestSfinae['float']()
testing.test_single(1)  # good
testing.test_pack(1,2,3)  # fails

Which fails with the message

input_line_24:6:70: error: no matching member function for call to 'test_pack'
      new (ret) (int) (((TestSfinae<float>*)obj)->TestSfinae<float>::test_pack<int, int, int, float, false>(*(int*)args[0], *(int*)args[1],
                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
input_line_18:11:8: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Args'
  auto test_pack(Args... args) {
       ^

Which (again, seems to me) has to do with cppyy explicitly providing the SFINAE template parameters somewhere in the process of passing the call down to its C++-binding.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions