1

I have c++ class and need to use it in python code. For that using swig to generate a wrapper class. As per the documentation configured the example.i

/* File: example.i */
%module example

%{
#define SWIG_FILE_WITH_INIT
#include "item.h"
#include "GradedComplex.h"
#include "GradedDouble.h"
%}

%include "item.h"
%include "GradedComplex.h"
%include "GradedDouble.h"

And I am trying to build a wrapper class using swig in windows

c:>swig -c++ -python example.i

c:>python setup.py build_ext --inplace

After executing second command I am getting following error.

example_wrap.cxx
C:\Program Files\Microsoft Visual Studio 9.0\VC\INCLUDE\xlocale(342) : warning C
4530: C++ exception handler used, but unwind semantics are not enabled. Specify
/EHsc
c:\documents and settings\swig\item.h(73) : warning C45
21: 'Item<std::complex<double>>' : multiple copy constructors specified
c:\documents and settings\swig\item.h(57) : error C2106
: '+=' : left operand must be l-value
c:\documents and settings\swig\item.h(58) : error C2106
: '+=' : left operand must be l-value
c:\documents and settings\swig\item.h(63) : error C2106
: '-=' : left operand must be l-value
c:\documents and settings\swig\item.h(64) : error C2106
: '-=' : left operand must be l-value
c:\documents and settings\swig\item.h(69) : error C2106
: '=' : left operand must be l-value
c:\documents and settings\swig\item.h(70) : error C2106
: '=' : left operand must be l-value
example_wrap.cxx(3275) : error C2512: 'Item<std::complex<double>>' : no appropriate default constructor available

c:\documents and settings\swig\Item.h(38) : warning C45
21: 'Item<T>' : multiple copy constructors specified
        with
        [
            T=double
        ]
        example_wrap.cxx(3425) : see reference to class template instantiation '
Item<T>' being compiled
        with
        [
            T=double
        ]
error: command '"C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\cl.exe"' fa
iled with exit status 2

The item.h is the following

#ifndef __ITEM_H__
#define __ITEM_H__

#include <complex>
#include <functional>
#include <string>

template<typename T>
class Item
{
  std::string name_;
  T val_;

public:
  Item(std::string name, T val) : name_(name), val_(val) {}
  Item(Item<T> &rhs) : name_(rhs.name_), val_(rhs.val_) {}
  Item(const Item<T> &rhs) : name_(rhs.name_), val_(rhs.val_) {}
  ~Item() {}

  std::string name() const { return name_; }
  T operator()() const { return val_; }
  double norm() const { return sqrt(val_ * val_); }
  Item<T> &operator+=(Item<T> &rhs)
  {
    val_ += rhs();
    return *this;
  }
  Item<T> &operator-=(Item<T> &rhs)
  {
    val_ -= rhs();
    return *this;
  }
  Item<T> &operator*=(Item<T> &rhs)
  {
    val_ *= rhs();
    return *this;
  }
};

template<>
class Item<std::complex<double> >
{
  std::string name_;
  std::complex<double> val_;

public:
  Item(std::string name, std::complex<double> val) : name_(name), val_(val) {}
  Item(Item<std::complex<double> > &rhs) : name_(rhs.name_), val_(rhs.val_) {}
  Item(const Item<std::complex<double> > &rhs) : name_(rhs.name_), val_(rhs.val_) {}
  ~Item() {}

  std::string name() const { return name_; }
  std::complex<double> operator()() const { return val_; }
  double norm() const { return sqrt(val_.real() * val_.real() + val_.imag() * val_.imag()); }
  Item<std::complex<double> > &operator+=(Item<std::complex<double> > &rhs)
  {
    val_.real() += rhs().real();
    val_.imag() += rhs().imag();
    return *this;
  }
  Item<std::complex<double> > &operator-=(Item<std::complex<double> > &rhs)
  {
    val_.real() -= rhs().real();
    val_.imag() -= rhs().imag();
    return *this;
  }
  Item<std::complex<double> > &operator*=(Item<std::complex<double> > &rhs)
  {
    val_.real() = val_.real() * rhs().real() - val_.imag() * rhs().imag();
    val_.imag() = val_.real() * rhs().imag() + val_.imag() * rhs().real();
    return *this;
  }
};

template<typename T>
struct ItemComparator : public std::binary_function<Item<T>, Item<T>, bool>
{
  inline bool operator()(Item<T> lhs, Item<T> rhs)
  {
    return lhs.norm() < rhs.norm();
  }
};

#endif

1 Answer 1

1

You have errors in the C++ code. std::complex::real() does not return an lvalue, so this does not compile:

  Item<std::complex<double> > &operator+=(Item<std::complex<double> > &rhs)
  {
    val_.real() += rhs().real();
    val_.imag() += rhs().imag();
    return *this;
  }

You could just use this:

val_ += rhs();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.