I'm getting the error call of overloaded function is ambiguous and I understand it's because the compiler can't differentiate between them, but is there a way to work around this while maintaining the same parameters? I have to use the declarations I've provided below and it's confusing me as to how I can use them both if I met with this error every time.
I've shortened my code to show the constructors that are posing the issue.
ErrorMessage.h
class ErrorMessage {
char* message_; //pointer that holds the address of the message stored in current object
public:
ErrorMessage();
explicit ErrorMessage(const char* errorMessage = nullptr); //receive address of a C-style nullterminate string holding an error message
}
ErrorMessage.cpp
namespace sict {
ErrorMessage::ErrorMessage() {
message_ = nullptr;
}
ErrorMessage::ErrorMessage(const char* errorMessage) {
if(errorMessage == nullptr) {
message_ = nullptr;
}
else {
message(errorMessage);
}
const char* ErrorMessage::message() const {
return message_;
}
}
Just remove the constructor which takes no parameters. The second constructor already does everything the first constructor does.
If it receives a nullptr, it tests it and sets the local variable, if not it continues with its logic. The first constructor is completely superfluous.
Related
class mapInfo
{
public:
mapInfo();
~mapInfo();
public:
int dataType_m;
private:
int *frequency;
};
//constructor is defined here.
mapInfo::mapInfo() :
dataType_m(0),
frequency(NULL)
{
}
//destructor is defined here
mapInfo::~mapInfo()
{
free(frequency);
frequency = NULL;
}
Result_t Maps::add(mapInfo &mapInfo_r)
{
if (maps_mp == NULL)
{
numMaps_m = 1;
maps_mp = (mapInfo *) calloc(1, sizeof(mapInfo));
}
else
{
numMaps_m++;
maps_mp = (mapInfo *) realloc(maps_mp, numMaps_m*sizeof(mapInfo));
}
maps_mp[numMaps_m-1] = mapInfo_r; // Default copy constructor
return 1;
}
While compiling with gcc8, getting the following compilation error. It looks like defining the destructor like above giving the compilation error for gcc8.
How to resolve this?
error: 'void* realloc(void*, size_t)' moving an object of non-trivially copyable type 'class xyyz::mapInfo'; use 'new' and 'delete' instead [-Werror=class-memaccess].
That’s simply not proper C++. Rewrite your code as follows (I’m guessing here with regards to the type of frequency, but definitely don’t use free on it):
#include <vector>
class map_info
{
public:
map_info();
private:
int data_type;
std::vector<int> frequency;
};
std::vector<map_info> maps_mp;
map_info::map_info() : data_type(0), frequency() {}
// …
void maps::add(map_info& map_info)
{
maps_mp.push_back(map_info);
}
maps_mp = (mapInfo *) realloc(maps_mp, numMaps_m*sizeof(mapInfo));
This is not sensible. You can't just move an object from one aree of memory to another if that object is non-trivial.
For example, consider a string object that keeps a pointer to the string. It could look like this:
class MyString
{
char* inner_ptr;
char buf[64];
...
};
And it might have a constructor like this:
MyString::MyString (const char* j)
{
if (strlen(j) < 64)
inner_ptr = buf;
else
inner_ptr = malloc (strlen(j) + 1);
strcpy(inner_ptr, j);
}
And a destructor like this:
MyString::~MyString()
{
if (buf != inner_ptr)
free (inner_ptr);
}
Now, think about what happens if you call relloc on an array of these. The short strings will still have their inner_ptrs pointing to the old object's buffer, which you just deallocated.
The error message explains this issue reasonable well. It is simply not legal to use realloc to move a non-trivial object. You have to construct a new object because the object needs a chance to handle the change in its address.
I have a simple class:
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- Ambiguity is here! I want to call 'void f()'
}
I want to resolve ambiguity of a method call in favour of the exception-throwing method by any means.
The rationale behind such interface:
To have the noexcept(true) and noexcept(false) interface,
To allow optionally get extra information via a pointer in the noexcept(false) variant - while the noexcept(true) variant will always pack this information inside an exception.
Is it possible at all? Suggestions for a better interface are also welcome.
Having functions with this kind of signatures is obviously a bad design as you've found out. The real solutions are to have different names for them or to lose the default argument and were presented already in other answers.
However if you are stuck with an interface you can't change or just for the fun of it here is how you can explicitly call void f():
The trick is to use function pointer casting to resolve the ambiguity:
a.f(); // <- ambiguity is here! I want to call 'void f()'
(a.*(static_cast<void (A::*)()>(&A::f)))(); // yep... that's the syntax... yeah...
Ok, so it works, but don't ever write code like this!
There are ways to make it more readable.
Use a pointer:
// create a method pointer:
auto f_void = static_cast<void (A::*)()>(&A::f);
// the call is much much better, but still not as simple as `a.f()`
(a.*f_void)();
Create a lambda or a free function
auto f_void = [] (A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
// or
void f_void(A& a)
{
auto f_void = static_cast<void (A::*)()>(&A::f);
(a.*f_void)();
};
f_void(a);
I don't know if this is necessary better. The call syntax is definitely simpler, but it might be confusing as we are switching from a method call syntax to a free function call syntax.
Both versions f have different meanings.
They should have two different name, as:
f for the throwing one, because using it means that your are confident on success, and failure would be an exception in the program.
try_f() or tryF() for the error-return based one, because using it means that failure of the call is an expected outcome.
Two different meanings should be reflected in the design with two different name.
Because it seems fundamentally obvious to me, I may be missing something or may not fully understand your question. However, I think this does exactly what you want:
#include <utility>
class A {
public:
bool f(int* status) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // <- now calls 'void f()'
a.f(nullptr); // calls 'bool f(int *)'
}
I simply removed the default argument from the noexcept variant. It's still possible to call the noexcept variant by passing nullptr as an argument, which seems a perfectly fine way of indicating that you want to call that particular variant of the function - after all, there's going to have to be some syntactic marker indicating which variant you want to call!
I agree with other users' suggestions to simply remove the default argument.
A strong argument in favour of such a design is that it would be in line with the new C++17 filesystem library, whose functions typically offer callers the choice between exceptions and error reference parameters.
See for example std::filesystem::file_size, which has two overloads, one of them being noexcept:
std::uintmax_t file_size( const std::filesystem::path& p );
std::uintmax_t file_size( const std::filesystem::path& p,
std::error_code& ec ) noexcept;
The idea behind this design (which is originally from Boost.Filesystem) is almost identical to yours, except of the default argument. Remove it and you do it like a brand new component of the standard library, which obviously can be expected not to have a completely broken design.
In C++14 it's ambiguous because noexcept is not part of the function signature. With that said...
You have a very strange interface. Although f(int* status = nullptr) is labelled noexcept, because it has a twin that does throw a exception, you are not really giving the caller a logical exception guarantee. It seems you simultaneously want f to always succeed while throwing an exception if the precondition is not met (status has a valid value, i.e not nullptr). But if f throws, what state is the object in? You see, your code is very hard to reason about.
I recommend you take a look at std::optional instead. It'll signal to the reader what you are actually trying to do.
C++ already has a type specifically used as an argument to disambiguate between throwing and non-throwing variants of a function: std::nothrow_t. You can use that.
#include <new>
class A {
public:
bool f(std::nothrow_t, int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
int main() {
A a;
a.f(); // Calls 'void f()'
a.f(std::nothrow); // Calls 'void f(std::nothrow_t, int*)'
}
Though I would still prefer an interface where the name distinguishes the variants, or possibly one where the distinction isn't necessary.
Here's a purely compile-time method.
It may be useful if your compiler happens to have trouble optimizing away function pointer calls.
#include <utility>
class A {
public:
bool f(int* status = nullptr) noexcept {
if (status) *status = 1;
return true;
}
void f() {
throw std::make_pair<int, bool>(1, true);
}
};
template<void (A::*F)()>
struct NullaryFunction {
static void invoke(A &obj) {
return (obj.*F)();
}
};
int main() {
A a;
// a.f(); // <- Ambiguity is here! I want to call 'void f()'
NullaryFunction<&A::f>::invoke(a);
}
So you are trying to throw an exception if the code is unprepared for an error return?
Then, how about
class ret
{
bool success;
mutable bool checked;
int code;
public:
ret(bool success, int code) : success(success), checked(false), code(code) { }
~ret() { if(!checked) if(!success) throw code; }
operator void *() const { checked = true; return reinterpret_cast<void *>(success); }
bool operator!() const { checked = true; return !success; }
int code() const { return code; }
};
This is still an Abomination unto Nuggan though.
By removing the if(!success) check in the destructor, you can make the code throw whenever a return code is not looked at.
I keep getting this error and I'm not sure how to correct it as I am given no errors in my code editors. I have looked up similar issues, but I am still having trouble to understand how to apply the solutions here. I've tried altering my code for several hours now, but to no avail. Any help would be appreciated. I have provided my .h and .cpp files below.
ErrorMessage.h
#ifndef SICT_ERRORMESSAGE_H
#define SICT_ERRORMESSAGE_H
#include <iostream>
namespace sict {
class ErrorMessage {
char* message_; //pointer that holds the address of the message stored in current object
public:
explicit ErrorMessage(const char* errorMessage = nullptr); //receive address of a C-style nullterminate string holding an error message
ErrorMessage(const ErrorMessage& em) = delete; //deleted copy constructor that prevents copying of an ErrorMessage object
ErrorMessage& operator=(const ErrorMessage& em) = delete; //deleted assignment operator that prevents assignment of ErrorMessage object to current object
virtual ~ErrorMessage(); //deallocates any memory that has been dynamically allocated by the current object
void clear(); //clears any message stored by current object and initialize object to safe, empty state
bool isClear() const; //return true if object is in a safe, empty state
void message(const char* str); //stores a copy of the C-style string pointed to by str
const char* message() const; //return address of the message stored in current object
};
//helper operator
std::ostream& operator<<(std::ostream& os, const ErrorMessage& err);
}
#endif
ErrorMessage.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
#include "ErrorMessage.h"
namespace sict {
ErrorMessage::ErrorMessage(const char* errorMessage) {
if(errorMessage == nullptr) {
message_ = nullptr;
}
else {
message(errorMessage);
}
}
ErrorMessage::~ErrorMessage() {
delete [] message_;
}
void ErrorMessage::clear() {
delete [] message_;
message_ = nullptr;
}
bool ErrorMessage::isClear() const {
if(message_ == nullptr) {
return true;
}
else {
return false;
}
}
void ErrorMessage::message(const char* str) {
delete [] message_;
message_ = new char[strlen(str) + 1];
strcpy(message_, str);
}
const char* ErrorMessage::message() const {
return message_;
}
std::ostream& operator<<(std::ostream& os, const ErrorMessage& err) {
if(!err.isClear()) {
os << err.message();
}
return os;
}
}
It's not surprising your code made it through editor syntax checks and compilation - it's valid code. It's just got an incorrect pointer somewhere.
This may mean that your'e accidentally dereferencing something , or perhaps passing a value somewhere you should be passing a pointer. You should get a compile time warning about that kind of stuff.
Another possibility is that you're failing to initialize some pointer, and its value happens to be 0xb75....
Clearly, neither you nor I are not likely to guess from whence this error originates. As Sam Varshavchik pointed out in a comment, you don't even know if the code you posted is the source of the error. Even if you guess your way through this one ( or perhaps keenly observe, Sam ), it's just plain silly to try to write C++ that way.
What you need is a debugger. A debugger is a program you run your program within, and it keeps track of the program's state so that when you have a memory violation, the debugger can produce a backtrace showing where in your source code the error occurred. You also have to compile your program with debugging support, so that the debugger has markers it can use to refer back to the source code.
It's a process far beyond the scope of your question, but one that's easy to learn about once you know what you're going for. Look for one that integrates with your IDE, if possible, as you're leveraging your development environment heavily. It's not unlikely that you already have it set up- you might just need to use it. Search for C++ debugging in the context of your editor first - if it turns up nothing, consider searching under your compiler suite, whatever that may be ( if your'e using open source, you're probably using gcc, and the matching debugger is gdb ).
You're about to gain a far more accurate understanding of what it is to program C / C++. Good luck.
I have a functional object that I'm using as body for multifunction_node:
class module
{
private:
bool valid;
QString description;
bool hasDetectionBranch;
tDataDescription bufData;
void* dllObject; //<-- This is a pointer to an object constructed with help of the external dll
qint64 TimeOut;
public:
module(const QString& _ExtLibName);
virtual ~module();
void operator() (pTransmitData _transmitData, multi_node::output_ports_type &op);
};
'dllObject' is created at construction time of the object 'module':
module::module(const QString& _ExtLibName) :
valid(true), hasDetectionBranch(false)
{
GetObjectDescription = (tGetObjectDescription)QLibrary::resolve(_ExtLibName, "GetObjectDescription");
CreateObject = (tCreateObject)QLibrary::resolve(_ExtLibName, "CreateObject");
DestroyObject = (tDestroyObject)QLibrary::resolve(_ExtLibName, "DestroyObject");
if (!CreateObject || !DestroyObject || !GetObjectDescription)
valid = false;
else
{
description = QString(GetObjectDescription());
dllObject = CreateObject();
}
}
And this is when 'dllObject' is destroyed:
module::~module()
{
if (valid)
{
DestroyObject(dllObject);
}
}
I've built a little graph:
void MainWindow::goBabyClicked(void)
{
module mod(QString("my.dll")); //<-- Here is OK and mod.dllObject is correct
if (!mod.isValid())
{
qDebug() << "mod is invalid!\n";
return;
}
first fir(input);
folder fol(QString("C:/out"), 10000);
graph g;
source_node<pTransmitData> src(g, fir, false);
multi_node mnode(g, tbb::flow::serial, mod); //<-- WTF? ~module() is executed!
function_node<pTransmitData> f(g, tbb::flow::serial, fol);
make_edge(src, mnode);
make_edge(mnode, f);
src.activate();
g.wait_for_all();
}
So I have 2 questions:
1) Why ~module() is executed and how to prevent this?
2) How to keep pointer for nested object correctly?
UPDATE Added some dummy code to prevent destroying dllObject at first time like:
bool b = false;
module::~module()
{
if (valid && b)
{
DestroyObject(dllObject);
}
if (!b)
b = true;
valid = false;
}
Now it works as expected but looks ugly :/
Max,
I assume you have a typedef of multi_node which is similar to the one in the reference manual example.
The constructor for the multifunction_node has the following signature:
multifunction_node( graph &g, size_t concurrency, Body body );
The body object is copied during the parameter passing and also during the construction of the node, so there are two copies of mod created during construction (actually three, as an initial copy of the body is also stored for re-initializing the body when calling reset() with rf_reset_bodies). The destructor calls you are seeing are probably those used to destroy the copies.
The body object should also have a copy-constructor defined or be able to accept the default-copy-constructor to make copies of the body. I think the QString has a copy-constructor defined, but I don't know about fields like tDataDescription. (I thought we had covered the basic requirements for Body objects in the Reference Manual, but I am still looking for the section.) In any case, the Body class must be CopyConstructible, as it is copied multiple times.
Regards,
Chris
Error received:
error: no matching function for call to ‘stout::SCGI::SCGI()’
Code:
#include <gtest/gtest.h>
#include <vector>
#include "../../../../stout/cgi/scgi/scgi.hpp"
class SCGITest : public ::testing::Test
{
protected:
int string_length;
std::vector<char> netstring;
stout::SCGI scgi;
public:
SCGITest()
{
const char *c_netstring =
"70:CONTENT_LENGTH\00027\0"
"SCGI\0001\0"
"REQUEST_METHOD\0POST\0"
"REQUEST_URI\0/deepthought\0"
","
"What is the answer to life?";
string_length = 102;
for(int i = 0; i < string_length; ++i)
{
netstring.push_back(c_netstring[i]);
}
// SHOULD CALL stout::SCGI::SCGI(const std::vector<char>&)
this->scgi = stout::SCGI scgi {netstring};
scgi.init();
}
};
TEST_F(SCGITest, NetstringSize)
{
EXPECT_EQ(netstring.size(), string_length);
}
TEST_F(SCGITest, SCGILength)
{
EXPECT_EQ(scgi.get_length(), 70);
}
TEST_F(SCGITest, SCGIContentLength)
{
EXPECT_EQ(scgi.get_header("CONTENT_LENGTH"), "27");
}
TEST_F(SCGITest, SCGIVersion)
{
EXPECT_EQ(scgi.get_header("SCGI"), "1");
}
TEST_F(SCGITest, SCGIRequestMethod)
{
EXPECT_EQ(scgi.get_header("REQUEST_METHOD"), "POST");
}
TEST_F(SCGITest, SCGIRequestURI)
{
EXPECT_EQ(scgi.get_header("REQUEST_URI"), "/deepthought");
}
TEST_F(SCGITest, SCGIRequestBody)
{
EXPECT_EQ(scgi.get_request_body(), "What is the answer to life?");
}
Question:
When I try and construct and object of type stout::SCGI::SCGI using the constructor stout::SCGI::SCGI(const std::vector<char>&) it fails in the above code with the error message shown at the top of this post.
It seems that before the constructor has finished it has already tried to call the default (empty) constructor for the scgi private member variable. I do not want an empty constructor on my class and have had to temporarily add one to fix this issue while I investigate it.
I've read other questions regarding this issue but can't seem to find a solution for this particular case.
If it matters I'm compiling the above code using G++ 4.9.2 on Arch Linux with the -std=c++14 flag.
Your stout::SCGI type has no default constructor, yet you are not initialising this->scgi. Sure, you're assigning to it at the end of your constructor body, but that's not at all the same thing.
You need to initialise any members that are const or which cannot be default-constructed:
struct Foo
{
stout::SCGI scgi;
Foo()
: scgi(/* ctor arguments here */) // this is a "member initialisation list"
{};
};
Also, the following is simply not valid syntax:
this->scgi = stout::SCGI scgi {netstring};
That lone scgi is clearly superfluous. At best, you want:
this->scgi = stout::SCGI{netstring};
However, once you're initialising this->scgi instead of waiting to assign to it, then this goes away completely.
What is scgi supposed to be here? I think you just want
this->scgi = stout::SCGI {netstring};