2

This is very related to this question

Regardless of whether or not this is coding practice, I have come across code that looks like this

test.hh

#include <vector>                                                                                   
using std::vector;                                                             

class Test 
{                                                                     
    public:                                                                      
        vector<double> data;                                                     
};  

I am trying to swig this using swig3.0 using the following interface file

test.i

%module test_swig                                                                

%include "std_vector.i"                                                          

namespace std {                                                                  
    %template(VectorDouble) vector<double>;                                      
};                                                                               

%{                                                                               
    #include "test.hh"                                                               
%}                                                                               

%naturalvar Test::data;                                                                                 
%include "test.hh"    

And the following test code

test.py

t = test.Test()                                                              
jprint(t)                                                                    
a      = [1, 2, 3]                                                                
t.data = a # fails   

doing so gives me the following error

in method 'Test_data_set', argument 2 of type 'vector< double >'

This can be fixed by either changing the using std::vector in test.hh to using namespace std or by removing using std::vector and changing vector<double> to std::vector<double>. This is not what I want.

The problem is that I was given this code as is. I am not allowed to make changes, but I am supposed to still make everything available in python via SWIG. What's going on here?

Thanks in advance.

Community
  • 1
  • 1
jrk0414
  • 144
  • 1
  • 1
  • 11

1 Answers1

2

To me, this looks like SWIG does not support the using std::vector; statement correctly. I think it's a SWIG bug. I can think of the following workarounds:

  • Add using namespace std; to the SWIG interface file (this will only affect the way wrappers are created; the using statement will not enter C++ code)
  • Add #define vector std::vector to the SWIG interface file (this will only work if vector is never used as std::vector)
  • Copy the declarations from the header file to the SWIG interface file, and change vector to std::vector. This will cause SWIG to generate correct wrappers, and again will not affect the C++ library code.
m7thon
  • 3,033
  • 1
  • 11
  • 17
  • (Or just not force `using` on everyone by having them at global scope inside header files). – Flexo Jun 30 '16 at 06:43
  • I agree with Flexo, without a doubt. That might be the best way to handle this, but unfortunately, that was not the question. As far as m7thon's response, the first bullet seems to override the `using std::vector` in the h file. Very nice! The other options are iffy, but I'll count it as closed because of the first bullet. – jrk0414 Jun 30 '16 at 20:20
  • The third point (copying and customizing the declarations) is in some sense the "correct" way to go and guaranteed to work. Using `%include "test.hh"` is really a shortcut for when the header file can be used as is. The first two points are hacks, but if they work... ;-) – m7thon Jun 30 '16 at 21:47