iclcv/icl

unrecognizable template declaration/definition

Closed this issue · 4 comments

Building ICL with MSVC (Visual Studio 15/2017) results in the following error:

"E:\icl\build\ALL_BUILD.vcxproj" (default target) (1) ->
"E:\icl\build\ICLCV\ICLCV.vcxproj" (default target) (3) ->
"E:\icl\build\ICLCore\ICLCore.vcxproj" (default target) (4) ->
"E:\icl\build\ICLMath\ICLMath.vcxproj" (default target) (5) ->
(ClCompile target) ->
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(178): error C2988: unrecognizable template declaration/definition
 [E:\icl\build\ICLMath\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(178): error C2059: syntax error: '(' [E:\icl\build\ICLMath\ICLMat
h.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(178): error C2143: syntax error: missing ';' before '{' [E:\icl\b
uild\ICLMath\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(178): error C2447: '{': missing function header (old-style formal
 list?) [E:\icl\build\ICLMath\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(183): error C2065: 'r': undeclared identifier [E:\icl\build\ICLMa
th\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(183): error C2470: 'icl::math::PolynomialRegression<T>::Result::operator =': looks like a function definition, but there is no parameter list; skipping apparent body [E:\icl\build\ICLM
ath\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(183): error C2072: 'icl::math::PolynomialRegression<T>::Result::operator =': initialization of a function [E:\icl\build\ICLMath\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\PolynomialRegression.cpp(183): error C2447: '{': missing function header (old-style formal list?) [E:\icl\build\ICLMath\ICLMath.vcxproj]
  E:\icl\ICLMath\src\ICLMath\SimplexOptimizer.cpp : fatal error C1128: number of sections exceeded object file format l
imit: compile with /bigobj [E:\icl\build\ICLMath\ICLMath.vcxproj]

The first error is about this template from here:

template<class T>
PolynomialRegression<T>::Result::Result(const PolynomialRegression<T>::Result &r){
  *this = r;
}

I cannot really tell whats going wrong there. @celbrech, @scires: any idea?

Its actually just these two functions that cause the errors:

    template<class T>
    PolynomialRegression<T>::Result::Result(const PolynomialRegression<T>::Result &r){
      *this = r;
    }
    

    template<class T>
    typename PolynomialRegression<T>::Result &PolynomialRegression<T>::Result::operator=(const PolynomialRegression<T>::Result &r){
      for(size_t i=0;i<m_attribs.size();++i){
        delete m_attribs[i];
      }
      m_attribs.resize(r.m_attribs.size());
      for(size_t i=0;i<m_attribs.size();++i){
        m_attribs[i] = r.m_attribs[i]->copy();
      }

      m_function = r.m_function;
      m_params = r.m_params;
      m_xbuf = r.m_xbuf;
      m_resultBuf = r.m_resultBuf;
      m_attribMaxIndex = r.m_attribMaxIndex;
      return *this;
    }

The rest seems to compile just fine (except this big object file thing which I will investigate later)

I could boil it down to:

#pragma once

template<class T>
class PolynomialRegression{
  class Result{
    friend class PolynomialRegression;
    public:
      Result(const Result &r);
  };
};
#include <ICLMath/PolynomialRegression.h>

template<class T>
PolynomialRegression<T>::Result::Result(const PolynomialRegression<T>::Result &r){
  *this = r;
}

Still causes the same error. This means, it's not a namespace thing and also not related to compat macros.

Posted on SO.

Okay, MSCV requires

PolynomialRegression<T>::Result::Result(const PolynomialRegression<T>::Result &r){

to be

PolynomialRegression<T>::Result::Result(const typename PolynomialRegression<T>::Result &r){

If someone has a clue why typename is required for MSVC but not for Clang/GCC, please enlighten me.