Use a #define VALUE with a template - c++

i cannot pass defined values to a template. Even a simple calculation doesnt work:
#define IR_TIMEOUT 564*173/2
return decodeSpace<IR_TIMEOUT>(
duration);
return decodeSpace<564*173/2>(
duration);
Working:
return decodeSpace<48786>(
duration);
The definition:
template <uint16_t irTimeout>
bool decodeSpace(unsigned long duration){}
The error:
E:\Arduino\sketchbook\libraries\IRLremote\IRLprotocolNEC.cpp: In member function 'virtual bool IRLprotocolNEC::decodeIR(long unsigned int)':
E:\Arduino\sketchbook\libraries\IRLremote\IRLprotocolNEC.cpp:46:11: error: no matching function for call to 'IRLprotocolNEC::decodeSpace(long unsigned int&)'
duration);
^
E:\Arduino\sketchbook\libraries\IRLremote\IRLprotocolNEC.cpp:46:11: note: candidate is:
In file included from E:\Arduino\sketchbook\libraries\IRLremote/IRLprotocolNEC.h:27:0,
from E:\Arduino\sketchbook\libraries\IRLremote\IRLprotocolNEC.cpp:24:
E:\Arduino\sketchbook\libraries\IRLremote/CIRLremote.h:103:9: note: template bool CIRLprotocol::decodeSpace(long unsigned int)
bool decodeSpace(unsigned long duration){
^
E:\Arduino\sketchbook\libraries\IRLremote/CIRLremote.h:103:9: note: template argument deduction/substitution failed:
E:\Arduino\sketchbook\libraries\IRLremote\IRLprotocolNEC.cpp:46:11: error: overflow in constant expression [-fpermissive]
duration);
^
E:\Arduino\sketchbook\libraries\IRLremote\IRLprotocolNEC.cpp:46:11: note: in template argument for type 'unsigned int'
Is this a bug or a feature? Or better: How can i avoid/solve things like this?
I want to create different different decoding functions with the same structure but different timings. Passing the values takes a lot of flash so i better copy the function over and over. Thatswhy i wanted to use templates.

The problem is that 564*173 overflow uint16.
Use a define or a direct expression is the same thing when it comes for constant folding.
Constant folding is the fact that the compiler "expand" your expression. For example, replace "2*3" with "6".

The problem was that i needed to declare the calculation itself as long:
define IR_TIMEOUT 564UL*173/2
Thx # Matt McNabb

Related

To solve ambiguity of overloaded function without either adding typecasting or remove the overloaded functions

I made a class Dummy, which is just a wrapper of primitive type double. The purpose of the class is to test potential problems before I introduce another class that substitutes the double class.
Dummy.h:
class Dummy{
private:
double content;
public:
Dummy(double _content) :content{ _content } {};
operator long int() {return (long int)content;};
}
test.cpp:
#include <math.h>
int main(){
Dummy a = Dummy(1.1);
double aa = fabs(a);
}
It reports:
<source>:17:27: error: call of overloaded 'fabs(Dummy&)' is ambiguous
17 | std::cout << std::fabs(foo);
| ~~~~~~~~~^~~~~ In file included from /usr/include/features.h:461,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/x86_64-linux-gnu/bits/os_defines.h:39,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/x86_64-linux-gnu/bits/c++config.h:586,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/cmath:41,
from <source>:1: /usr/include/x86_64-linux-gnu/bits/mathcalls.h:162:1: note: candidate:
'double fabs(double)'
162 | __MATHCALLX (fabs,, (_Mdouble_ __x),
(__const__));
| ^~~~~~~~~~~ In file included from <source>:1: /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/cmath:241:3:
note: candidate: 'constexpr float std::fabs(float)'
241 |
fabs(float __x)
| ^~~~ /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/cmath:245:3:
note: candidate: 'constexpr long double std::fabs(long double)'
245 | fabs(long double __x)
If I add a type conversion operator:
operator double(){
return content;
}
It somehow only works under Visual Studio, not g++ 9.3.0, which is my target compiler.
During the compiling with g++ 9.3.0, the following errors are reported:
I have read the information here, unfortunately I can't remove the overloaded functions in this case. Neither can I add typecasting, because it doesn't make sense for my purpose.
I also check here, but I am not so familiar with templates. Hence my question is:
Can I eliminate the ambiguity of overloaded function within the class, without adding typecasting, or removing the overloaded functions?
The Dummy class you have shown is only convertible to long int, but fabs() does not accept long int, it accepts either float, double, or long double. Since long int is implicitly convertible to float and double, the call was ambiguous until you added the double conversion operator.
If you don't want to do that, then you have to be explicit about which overload of fabs() you want to call. Either by:
casting the result of the Dummy conversion:
double aa = fabs(static_cast<double>(a));
assigning/casting fabs() to a function pointer of the desired signature:
double (*fabs_ptr)(double) = fabs;
fabs_ptr(a);
using fabs_ptr = double (*)(double);
static_cast<fabs_ptr>(fabs)(a);
Online Demo

Cannot convert string to char* for argument 1

I am having an issue with my C++ code for converting a string of numbers in base b to another base n. My error is as follows:
cannot convert ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ to ‘char*’ for argument ‘1’ to ‘int base_to_decimal(char*, int)’
I am using g++ to compile, and I have been for a while, so I thought at first I knew what the issue was. It says that the method base_to_decimal accepts two arguments: one of type char* and one of type int. So all I should have to do to fix my issue is change the char* argument to a string, right?
Well, I looked, and the code for the function in question is:
int base_to_decimal(std::string input_base, int base)
So this method SHOULD be expecting a string, but for some reason when I pass in a string, it gets angry at me.
If someone could help me figure this out, that would be fantastic. I am using g++ 7.3.0, and running all this on Linux Mint 19.1.
(EDIT)
Main Method
Functions
Table
You've written a custom declaration on line 46 of your main:
int base_to_decimal(char * input_base, int base)
But in the functions file where you've defined your function, you have:
int base_to_decimal(std::string input_base, int base)
This is why you should not write in-line declarations for external functions, but instead put the declarations in a header file. #include in the file where the function is later defined, ensures that the definition matches the declaration that the other files are expecting. And likewise, it enforces that all those other files are trying to use the function the way it's actually coded.

error: no matching function for call to ‘ompl::tools::SelfConfig::getDefaultNearestNeighbors(ompl::geometric::RRT*)’

when compiling my own project, I got an error as follows:
myRRT.cc:80:78: error: no matching function for call to ‘ompl::tools::SelfConfig::getDefaultNearestNeighbors(ompl::geometric::RRT*)’
nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Motion *>(this));
^
In file included from /home/htf/Downloads/Active-ORB-SLAM2-octomap/src/myRRT.cc:36:0:
/opt/ros/indigo/include/ompl/tools/config/SelfConfig.h:93:42: note: candidate: template<class _T> static ompl::NearestNeighbors<_T>* ompl::tools::SelfConfig::getDefaultNearestNeighbors(const StateSpacePtr&)
static NearestNeighbors<_T>* getDefaultNearestNeighbors(const base::StateSpacePtr &space)
^
/opt/ros/indigo/include/ompl/tools/config/SelfConfig.h:93:42: note: template argument deduction/substitution failed:
/home/htf/Downloads/Active-ORB-SLAM2-octomap/src/myRRT.cc:80:78: note: cannot convert ‘(ompl::geometric::RRT*)this’ (type ‘ompl::geometric::RRT*’) to type ‘const StateSpacePtr& {aka const boost::shared_ptr<ompl::base::StateSpace>&}’
nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Motion *>(this))
here is a part of my source code,
void ompl::geometric::RRT::setup()
{
Planner::setup();
tools::SelfConfig sc(si_, getName());
sc.configurePlannerRange(maxDistance_);
if (!nn_)
nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Motion *>(this));
nn_->setDistanceFunction(std::bind(&RRT::distanceFunction, this, std::placeholders::_1, std::placeholders::_2));
}
this is one of a example file what I have referedRRT
does anyone have encountered the similar question? i'am new to C++, hope to get some clues. thank you in advance.
ompl::tools::SelfConfig::getDefaultNearestNeighbors(ompl::geometric::RRT*)
so you should modify it like this:
nn_.reset(tools::SelfConfig::getDefaultNearestNeighbors<Motion>(*this));
maybe motion is the templete and (*this) means you want to call object using (*this)
I am also the green hand. I am not sure.

function pointer gives me “redeclared as different kind of symbol” error

I want to decloare a function pointer as:
char*(*palpr_recognize_rawimage)(OPENALPR*, unsigned char*, int, int, int, struct AlprCRegionOfInterest);
which is for a function prototype declared as:
char *openalpr_recognize_rawimage(OPENALPR *instance, unsigned char *pixelData, int bytesPerPixel, int imgWidth, int imgHeight, struct AlprCRegionOfInterest roi)
but I get this error on compilation:
‘char* (* palpr_recognize_rawimage)(OPENALPR*, unsigned char*, int, int, int, AlprCRegionOfInterest)’ redeclared as different kind of symbol
char*(*palpr_recognize_rawimage)(OPENALPR*, unsigned char*, int, int, int, struct AlprCRegionOfInterest);
^
One way to avoid retyping a complex definition and possibly making an error is to use decltype.
So, after your function prototype you can have:
using PFN = decltype(&openalpr_recognize_rawimage);
PFN myfunctionptr;
I've found the problem!
It was a simple typo in the typedef palpr_recognize_rawimage_type line:
I forgot to add the suffix _type to the type declaration and hence the type and the actual pointer had the same name - which obviously would cause troubles...
If I had looked past to first error from the compiler, I would have spotted the following: note: previous declaration and it would have been obvious that I mesed something up in my type naming.
--> It's worth it to not to only look at the first/top error but also look at least at the second one too - as you never know, it may provide a hint too!

GoogleMock and QString argument

I'm trying to use gmock with custom string type.
I have a method with QString argument which I want to mock:
MOCK_METHOD1(getValue, int(QString key));
I set an expectation:
EXPECT_CALL(mock, getValue("someKey"));
Got an error:
error: no matching function for call to 'MyMock::gmock_getValue(const char[8])'
include/gmock/gmock.h:9339:20: note: in definition of macro 'GMOCK_EXPECT_CALL_IMPL_'
((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
note: in expansion of macro 'EXPECT_CALL'
...
gmock/gmock.h:9730:7: note: no known conversion for argument 3 from 'const char [6]' to 'const testing::Matcher<const QString&>&'
gmock_##Method(GMOCK_MATCHER_(tn, F, 1) gmock_a1, \
But this works:
EXPECT_CALL(mock, getValue(QString("someKey")));
How can I use string arguments without wrapping each string literal with QString() ?
It is due to "someKey" is not a QString, it is a const char[8] as reported by the error and Google Test / Mock requires that the 2 classes are the same.
In the same way a compiler does not know if the value 10 is supposed to be int32 int64, uint32 or uint64, the same applies.