<?xml version="1.0" encoding="windows-1252"?>
<node id="989382" title="Re^2: Can't create XSUBs for C functions with a same name" created="2012-08-23 17:00:14" updated="2012-08-23 17:00:14">
<type id="11">
note</type>
<author id="281137">
davido</author>
<data>
<field name="doctext">
&lt;p&gt;Let's say the user has two (or more) functions that are overloaded (C++ obviously), and that it's not trivial to implement them as a single variable-parameter function.  Obviously XS can't deal with overloaded functions -- it's just too much a C++ thing.  But there is another hope, and one that's often used when using Inline::C or Inline::CPP to interface with external libraries: Write a wrapper function.
&lt;/p&gt;
&lt;p&gt;Another limitation of Inline::CPP is that you can't expose templates directly to Perl.  As with function overloading, Perl XS would have no idea what to do with template definitions.  And C++ wouldn't know how Perl intends to call the functions, and thus wouldn't be able to expand the templates at compile-time.  But once again, simple wrappers can easily hide templates from Perl/XS.&lt;/p&gt;
&lt;p&gt;Ok, we're not dealing with templates here... just overloading.  Either way the following will work.  Write a wrapper that accepts a variable argument list, and then dispatches a call to the overloaded functions based on how many args are provided.  It's a little cumbersome once you get more than a handful of variations to deal with, but I don't think people generally create more than a handful of overloads anyway (they just turn to templates, which is why I mentioned templates earlier).&lt;/p&gt;
&lt;p&gt;So here's a hybrid: The overloaded functions (which won't bind to Perl), and the wrapper (which will):
&lt;/p&gt;
&lt;c&gt;
use strict;
use warnings;
use v5.16;

use Inline CPP =&gt; 'DATA';

say multiadd( 1 );          # No dispatch; just return the value.
say multiadd( 1, 2 );       # Dispatch add( int, int ).
say multiadd( 1, 2, 3 );    # Dispatch add( int, int, int ).
say multiadd( 1, 2, 3, 4 ); # No dispatch; throw an exception.
__DATA__
__CPP__

#include &lt;stdexcept&gt;

// Overloaded functions: add(int,int), add(int,int,int): No (reliable*) Perl binding.

int add ( int a, int b ) {
  return a + b;
}

int add ( int a, int b, int c ) {
  return a + b + c;
}


// XS binding will be generated for multiadd().

int multiadd ( SV * a, ... ) {
  dXSARGS;
  try{
    switch ( items ) {
      case 1:  return SvIV(ST(0));
      case 2:  return add( SvIV(ST(0)), SvIV(ST(1)) );
      case 3:  return add( SvIV(ST(0)), SvIV(ST(1)), SvIV(ST(2)) );
      default: throw std::runtime_error(
        "multiadd() - Too many args in function call"
      );
    }
  }
  catch ( std::runtime_error msg ) {
    croak( msg.what() );  // Perl wants exceptions via croak.
  }
}
&lt;/c&gt;
&lt;p&gt;This same approach could be used to dispatch calls based on any function signature criteria; number of parameters, or data-types.  Additionally, a similar approach works for dispatching to template-generated functions or classes.&lt;/p&gt;
&lt;p&gt;&lt;small&gt;*(reliable): I think the last overload defined will bind via XS, but the others will be masked.  It's not worth even trying to call directly.&lt;/small&gt;&lt;/p&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-281137"&gt;
&lt;br /&gt;&lt;p&gt;Dave&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
989162</field>
<field name="parent_node">
989172</field>
</data>
</node>
