3

I am compiling a C++ library that use a C++ mathematics library Eigen3. However, the following codes introduce some syntax errors when compiling with VC2013:

template <typename Derived>
    inline Eigen::Transform<typename Derived::Scalar, 3, Eigen::Isometry> v2t(const Eigen::MatrixBase<Derived>& x_) {
    Eigen::Transform<typename Derived::Scalar, 3, Eigen::Isometry> X;
    Eigen::Matrix<typename Derived::Scalar, 6, 1> x(x_);
    X.template linear() = quat2mat(x.template block<3,1>(3,0));
    X.template translation() = x.template block<3,1>(0,0);
    return X;
  }

The error messages are as follows:

Error   C2059   syntax error : 'template'    
Error   C2039   'X' : is not a member of 'Eigen::Transform<float,3,1,0>'        
Error   C2059   syntax error : 'template'    
Error   C2039   'X' : is not a member of 'Eigen::Transform<float,3,1,0>'    

I have never saw codes like that X.template so I have no idea how I can do to correct this compilation error. Any ideas?

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
feelfree
  • 11,175
  • 20
  • 96
  • 167
  • 2
    What version of Eigen are you using? I grabbed the latest copy and couldn't find that code ... Is that code in the library your compiling that's then referencing Eigen?? .. `X.template linear()` should be something like `X.template linear()` or just simply `X.linear()` .. – txtechhelp Jul 19 '17 at 07:38
  • @txtechhelp I am not compiling Eigen, and it is a library that is using Eigen http://jacoposerafin.com/nicp/ – feelfree Jul 19 '17 at 07:41
  • `X.template` and `x.template` are not valid C++; what do you intend those expressions to mean? – Toby Speight Jul 19 '17 at 07:51
  • 3
    That's valid C++ actually. It's a `template` disambiguator, start from [this question](https://stackoverflow.com/questions/4077110/template-disambiguator). Admittedly not a widely used feature, could be an issue with the VS2013 compiler. – themiurge Jul 19 '17 at 07:54
  • @feelfree This might be a window related issue (http://jacoposerafin.com/nicp-qa/viewtopic.php?t=10), as already mentioned, the `X.template linear()` looks suspicious. – Holt Jul 19 '17 at 08:10
  • 1
    It looks like a template function that might be referenced in Windows and not other platforms (or something like that); since template deduction (and thus errors) only happen if the function is referenced. And according to the [`Eigen::Transform` docs](https://eigen.tuxfamily.org/dox/classEigen_1_1Transform.html#a9f8236005565db948b3b11860bc0a1cb), that function is not a templated function, thus the `template` disambiguator is not needed (hence the errors). Since it's in the 3rd party library and not Eigen, have you tried simply removing the `template` disambiguator? – txtechhelp Jul 19 '17 at 08:17
  • @Holt Thanks, and I will try to compile with VC2015 or linux. – feelfree Jul 19 '17 at 08:23

1 Answers1

3

The template keyword should be used here to disambiguate between a template and a comparison operator, e.g.:

struct X {
    template <int A>
    void f();
};

template <class T>
void g() {
    T t{};
    t.f<4>(); // Error - Do you want to compare t.f with 4 
              // or do you want to call the template t.f ?
}

Here you need t.template f<4>() to "disambiguate". The issue with the library you used is that Eigen::Transform<...>::linear is not a template member function, so the template keyword is not necessary here, and should not be used (I think).

[temps.name#5]

A name prefixed by the keyword template shall be a template-id or the name shall refer to a class template. [ Note: The keyword template may not be applied to non-template members of class templates. —end note ] [...]

MSVC is right, Eigen::Transform<...>::linear is a non-template member of a class template, so the template keyword should not be applied. The following example from the standard should be ill-formed but compiles perfectly well with gcc and clang:

template <class T> struct A {
    void f(int);
    template <class U> void f(U);
};

template <class T> void f(T t) {
    A<T> a;
    a.template f<>(t); // OK: calls template
    a.template f(t); // error: not a template-id
}

There is already an open issue about this regarding the library you use on github, but without any answers from the author... Your could update the header (ncip/bm_se3.h) yourself or fork the project and make a pull-request on github.

Holt
  • 36,600
  • 7
  • 92
  • 139