Eigen 3.3.4 compilation error on MIPS Compiler (C++98) - c++

I compile Eigen 3.3.4 under Multi-2000 (Green Hill) MIPS C++ compiler.
After I solved some align macro issue in Macros.h, I met a problem again for some template expression.
Find the Error Details as below. I know it should be some issue for my old C++ compiler, but anyone whom can propose an work around it will be greatly appreciated.
"C:\Eigen/Eigen/src/Core/util/Meta.h", line 389
: error:
expression must have pointer-to-class type
template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * =
0);
^
"C:\Eigen/Eigen/src/Core/util/Meta.h", line 389
: error:
incomplete type is not allowed
template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * =
0);
^
So The Problem must be inside expression as below. But I really can not figure it out.
template <typename C> static meta_yes testFunctor(C const *,typename enable_if<(sizeof(return_ptr<C>()->operator()())>0)>::type * = 0);
Update 8/25-> whether "typename enable_if" cause this?

Related

Couldn't deduce template parameter for Eigen::Matrix

When I try to compile the following function (forward) using MSVC 19.latest I get the following error message.
'Eigen::Matrix<float,ann_output_len<LayerNodeConfig...>::value,1,0,_Rows,1> forward(const
ArtificialNeuralNetwork<InputSize,LayerNodeConfig...> &,const Eigen::Matrix<float,Rows,1,0,_Rows,1> &)':
could not deduce template argument for 'const Eigen::Matrix<float,Rows,1,0,_Rows,1> &' from
'Eigen::Matrix<float,2,1,0,2,1>'
forward interface
template<int InputSize, int ... LayerNodeConfig>
auto forward(const ArtificialNeuralNetwork<InputSize, LayerNodeConfig...>& ann,
const RL::Arrayf<InputSize>& input)
-> typename ANN::output_t<LayerNodeConfig...>
In main function
RL::Arrayf<2> X;
auto Y = forward(sampling_policy, X);
Now what I don't understand is why can't the compiler substitute Rows and _Rows with 2.
Any insight is appreciated.
You can try the full code in godbolt.org using this link, https://godbolt.org/z/7Mj5ee and try to compile it yourself if you like.
Note: I tried to compile the same code with latest GCC compiler and it compiled.
Update - Mar 06, 2021:
I made a workaround by changing the interface of function forward to accept Eigen::DenseBase<Derived> instead of RL::Arrayf<InputSize>.
Anyone who is interested can read more about it here, https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html

Template Alias, Variable Template, and auto type deduction failing to deduce template argument

While working on my class declaration I'm having some confusion on how to use alias templates and template variables within in a non class template while trying to use auto type deduction.
Signal.h
#ifndef SIGNAL_H
#define SIGNAL_H
#include <cstdint>
template<typename T>
using TimeSignal = T;
using DiscreteTime = TimeSignal<std::uint8_t>;
using ContinuousTime = TimeSignal<double>;
class Signal {
private:
template<typename T>
static TimeSignal<T> time_;
double voltage_;
double current_;
public:
template<typename T>
explicit Signal( TimeSignal<T> time, double voltage = 0, double current = 0 ) :
voltage_{voltage}, current_{current}
{ time_ = time; }
double sampleVoltage() { return voltage_; }
double sampleCurrent() { return current_; }
template<typename T>
static auto atTime() { return time_; }
};
#endif // SIGNAL_H
And I would be using it like this:
#include <iostream>
#include "Signal.h"
int main() {
DiscreteTime t1{ 5 };
ContinuousTime t2{ 7.5 };
Signal s1{ t1, 3.5, 0.05 );
Signal s2{ t2, 4.3, 0.09 );
auto time1 = s1.atTime();
auto time2 = s2.atTime();
return 0;
}
I don't want to template this class, so I was thinking about having an internal variable template. Outside of the class I was trying to use a template alias to have the different "TimeSignals" be descriptive as a "DiscreteTime" is typically and integral type and a ContinousTime is a floating point or over the set of Real numbers. I was however templating the constructor of this class that takes in the TimeSignal type and wanted the class to deduce the or to auto resolve it's internal variable template to that type depending which of the two types were passed in. Finally I was trying to use auto type deduction to return that type.
I don't know if its the syntax or the usage but this has me stumped. I'm not sure how to get this to a working compile state.
This is the current compiler errors that Visual Studio 2017 is giving me.
1>------ Build started: Project: Circuit Maker Simulator, Configuration: Debug x64 ------
1>main.cpp
1>c:\...\main.cpp(15): error C2672: 'Signal::atTime': no matching overloaded function found
1>c:\...\main.cpp(15): error C2783: 'auto Signal::atTime(void)': could not deduce template argument for 'T'
1>c:\...\Signal.h(64): note: see declaration of 'Signal::atTime'
1>c:\...\main.cpp(24): error C2672: 'Signal::atTime': no matching overloaded function found
1>c:\...\main.cpp(24): error C2783: 'auto Signal::atTime(void)': could not deduce template argument for 'T'
1>c:\...\Signal.h(64): note: see declaration of 'Signal::atTime'
1>Done building project "Circuit Maker Simulator.vcxproj" -- FAILED.
The compiler error's obvious to what they are saying, but it's like they are screaming or yelling at me without any help, assistance or suggestions on how to fix or resolve this...
Edit
User rafix07 helped me quite a bit with his answer and it was helpful. I was missing a couple of things, two of them I may have eventually caught onto if I kept staring at it long enough and that was the use of the variable templates within the class needing it's template argument or parameter. The other was using the scope resolution operator in the main function to call the static function. I could of found them given some time.
The one issue that had me stumbling in circles was the fact that I had to explicitly instantiate the function template of the type I want when calling it. This is the one that would of had me pulling out my hair for ours...
After adjusting the code according to the link in his answer I'm now able to compile, however I am now getting linker errors for unresolved external symbols and it has to do with the template variables. Which shouldn't be a problem, just need to define it within a cpp file to resolve static variables.
First of all, atTime is static method so only way to call it is to use scope resolution operator ::. atTime takes no arguments, so T cannot be deduced, and you need to put type in template arguments list explicitly:
auto time1 = Signal::atTime<DiscreteTime>();
auto time2 = Signal::atTime<ContinuousTime>();
In ctor of Signal and atTime function you have to specify T for which variable template is accessed:
template<typename T>
explicit Signal( TimeSignal<T> time, double voltage = 0, double current = 0 ) :
voltage_{voltage}, current_{current}
{ time_<T> = time; }
Full working code is here.

Implicit instantiation of undefined template - Compiler Issue

I'm trying to compile a program that compiles and runs fine on a Linux system (using both g++ and clang++).
However, on my Mac, it gives a whole lot of errors similar to the one shown below:
The error comes on "flow".
Some other stackoverflow threads provide answers on providing forward definitions of templates, which I think is already provided on the line having template < typename....
Code Snippet:
namespace A {
template <typename T, unsigned NIN, unsigned NOUT, unsigned BUS_WIDTH = 16,
typename ARB_FN = cm_arb_rr<T, NIN>>
class cm_xbar : public as_module {
SC_HAS_PROCESS(cm_xbar);
public:
std::array<cm_fifo<T, BUS_WIDTH>, NIN> flow;
};
}
Error:
error: implicit instantiation of undefined template
'std::__1::array<A::cm_fifo<A::aspkt *, 16, 16>, 1>'
std::array<cm_fifo<T, BUS_WIDTH>, NIN> flow;
Any ideas on why this may be happening?
Thanks!

MSVC pointer type attributes

I recently ran into a compilation warning (promoted to error) using the 64-bit VS2013 compiler (update 3) making me aware of the existence of pointer type attributes.
The warning indicated a loss of precision as I was about to assign something of type 'Object *' to 'Object * __ptr32'.
I didn't hear about this '__ptr32' suffix yet, so I did some googling and found the following link: http://blog.aaronballman.com/2013/05/msvc-pointer-type-attributes/ .
After reading this, it became clear that I shouldn't simply ignore this warning as I might get ugly bugs in my 64-bit application...
Trying to pinpoint the problem further, I wrote following small program:
#include <type_traits>
struct O { };
struct OD { using V = O *; };
template <typename X, typename Y> struct expect_equal { static_assert(std::is_same<X, Y>::value, "Types do not correspond."); };
template <class D> using VD = typename D::V;
template <class D> struct Exp { template <template <class> class T> using DT = T<D>; };
int main(void)
{
expect_equal<Exp<OD>::DT<VD>, O *> e;
return 0;
}
While it would compile using clang, I got the following error/assertion failure using my MSVC 64-bit compiler (note: the 32-bit compiler did not yield compilation errors):
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30723 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
test.cpp
test.cpp(6) : error C2338: Types do not correspond.
test.cpp(13) : see reference to class template instantiation 'expect_equal<O * __ptr32,O *>' being compiled
I was wondering whether someone could indicate what I am doing wrong here: I don't use an explicit pointer type attribute anywhere. This also might be a an unspecified behavior or a bug of either the STL implementation or the compiler, but most likely I am missing some important point here... Thanks in advance!

error: cannot convert ‘int (^)(int)’ to ‘R (^)(T)’ in initialization

I am trying to understand how to best make use of blocks in my templated class.
I have the following code snippet:
template<typename T, typename R>
class MyClass {
public:
typedef R (^Block)(T);
MyClass(Block blk) {}
};
void testMyClass() {
MyClass<int,int>::Block blk(^(int arg) {
return 1 + arg;
});
}
When I try to compile this, I get the following error message:
error: cannot convert ‘int (^)(int)’ to ‘R (^)(T)’ in initialization
Am I missing something obvious? Am I trying to do something that is not allowed? GCC accepts the program if I do the same thing without templates.
This is an issue in GCC. I tested your program under LLVM 3 and it compiled just fine.
There are a number of problems in GCC 4.2's implementation of blocks, sometimes they can be worked around by fully qualifying your block declarations ^int(int arg){return 1 + arg;} but in this case it was unable to work around this issue. I would highly recommend moving to use LLVM/Clang for any further work with Obj-C Blocks. Its C++ support is very good these days, especially for C++03 support.