I'm compiling the following code
#include <iostream>
#include <stdexcept>
#include <string>
struct stack_error : public virtual std::logic_error {
using std::logic_error::logic_error;
//explicit stack_error(std::string const& what_arg) : std::logic_error(what_arg) {}
};
struct stack_empty_error : public stack_error {
explicit stack_empty_error(std::string const& what_arg) : std::logic_error(what_arg), stack_error(what_arg) {}
};
struct stack_full_error : public stack_error {
explicit stack_full_error(std::string const& what_arg) : std::logic_error(what_arg), stack_error(what_arg) {}
};
int main() {
stack_full_error e(std::string("WOW"));
std::cout << "ok" << '\n';
return 0;
}
with gcc 6.3 and I don't understand why it gives me the following error
(I think that the using std::error_logic... injects its 2 constructor in stack_error but if I use the commented out code everything is fine.
g++ -std=c++1z -Wall -Wextra -pedantic vbase.cpp -o vbase
(note clang++ compile it without error
clang++ -std=c++1z -Wall -Wextra -pedantic vbase.cpp -o vbase)
vbase.cpp: In constructor 'stack_empty_error::stack_empty_error(const string&)':
vbase.cpp:13:111: error: use of deleted function 'stack_error::stack_error(const string&)'
explicit stack_empty_error(std::string const& what_arg) : std::logic_error(what_arg), stack_error(what_arg) {}
^
vbase.cpp:6:27: note: 'stack_error::stack_error(const string&)' is implicitly deleted because the default definition would be ill-formed:
using std::logic_error::logic_error;
^~~~~~~~~~~
vbase.cpp:6:27: error: no matching function for call to 'std::logic_error::logic_error()'
In file included from C:/msys64/mingw64/include/c++/6.3.0/system_error:41:0,
from C:/msys64/mingw64/include/c++/6.3.0/bits/ios_base.h:46,
from C:/msys64/mingw64/include/c++/6.3.0/ios:42,
from C:/msys64/mingw64/include/c++/6.3.0/ostream:38,
from C:/msys64/mingw64/include/c++/6.3.0/iostream:39,
from vbase.cpp:1:
C:/msys64/mingw64/include/c++/6.3.0/stdexcept:128:5: note: candidate: std::logic_error::logic_error(const std::logic_error&)
logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
^~~~~~~~~~~
C:/msys64/mingw64/include/c++/6.3.0/stdexcept:128:5: note: candidate expects 1 argument, 0 provided
C:/msys64/mingw64/include/c++/6.3.0/stdexcept:124:5: note: candidate: std::logic_error::logic_error(const char*)
logic_error(const char*) _GLIBCXX_TXN_SAFE;
^~~~~~~~~~~
C:/msys64/mingw64/include/c++/6.3.0/stdexcept:124:5: note: candidate expects 1 argument, 0 provided
C:/msys64/mingw64/include/c++/6.3.0/stdexcept:120:5: note: candidate: std::logic_error::logic_error(const string&)
logic_error(const string& __arg) _GLIBCXX_TXN_SAFE;
^~~~~~~~~~~
C:/msys64/mingw64/include/c++/6.3.0/stdexcept:120:5: note: candidate expects 1 argument, 0 provided
vbase.cpp: In constructor 'stack_full_error::stack_full_error(const string&)':
vbase.cpp:19:110: error: use of deleted function 'stack_error::stack_error(const string&)'
explicit stack_full_error(std::string const& what_arg) : std::logic_error(what_arg), stack_error(what_arg) {}
Related
I have the following two files
foobar.h
#ifndef FOOBAR_H
#define FOOBAR_H
#include <cstring>
class Foo {
public:
int x;
Foo(int x);
};
class Bar {
public:
char* name;
Foo foo;
Bar(Foo foo);
};
#endif // FOOBAR_H
and foobar.cpp
#include "foobar.h"
Foo::Foo(int x) {
// Do something
}
Bar::Bar(Foo foo) {
// Do something
}
Attempting to compile these with g++ -c foobar.cpp -o foobar.o results in the following error:
foobar.cpp: In constructor ‘Bar::Bar(Foo)’:
foobar.cpp:9:17: error: no matching function for call to ‘Foo::Foo()’
Bar::Bar(Foo foo) {
^
foobar.cpp:5:1: note: candidate: ‘Foo::Foo(int)’
Foo::Foo(int x) {
^~~
foobar.cpp:5:1: note: candidate expects 1 argument, 0 provided
In file included from foobar.cpp:1:
foobar.h:5:7: note: candidate: ‘constexpr Foo::Foo(const Foo&)’
class Foo {
^~~
foobar.h:5:7: note: candidate expects 1 argument, 0 provided
foobar.h:5:7: note: candidate: ‘constexpr Foo::Foo(Foo&&)’
foobar.h:5:7: note: candidate expects 1 argument, 0 provided
As far as I understand the output of g++ is that it requires me to have a default constructor for foo. Why? I wish to pass a foo object to the constructor of bar, why would it need to invoke a default constructor anywhere? I do not want to have a no-args constructor anyways, since I NEED that x has a specific user defined value.
You are trying to default construct a Foo here:
Bar::Bar(Foo foo) {
// the member variable `foo` would have been default constructed here
// Do something
}
But Foo doesn't have a default constructor. One possible solution would be to initialize it in the member initializer list:
Bar::Bar(Foo foo) : foo(std::move(foo)) { // now uses the move constructor instead
// Do something
}
I'm trying to implement the move constructor outside the class body, but it won't compile correctly
#include <boost/move/move.hpp>
class Test
{
BOOST_COPYABLE_AND_MOVABLE(Test)
public:
Test() {}
Test(const Test & other) { }
Test(BOOST_RV_REF(Test) other);
Test & operator=(BOOST_COPY_ASSIGN_REF(Test) other) { return *this; }
Test & operator=(BOOST_RV_REF(Test) other) { return *this; }
};
Test::Test(BOOST_RV_REF(Test) other) { }
I compiled this code with g++, my g++ version is 4.4.7
$ g++ -c test.cpp
test.cpp:15: error: prototype for 'Test::Test(boost::rv<Test>&)' does not match any in class 'Test'
test.cpp:9: error: candidates are: Test::Test(boost:rv<Test>&)
test.cpp:8: error: Test::Test(const Test&)
test.cpp:7: error: Test::Test()
It also failed with g++ 5.4.0 – flyzero
Must be your boost version.
It works fine with g++ 5.4.1 and Boost 1.64. If not, check the preprocessor output for any include/macro mishaps.
In Linux, ::boost::rv is declared with may_alias attribute. My code compile correctly after removing the may_alias attribute.
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
template <class T>
class rv
: public ::boost::move_detail::if_c
< ::boost::move_detail::is_class<T>::value
, T
, ::boost::move_detail::nat
>::type
{
rv();
~rv() throw();
rv(rv const&);
void operator=(rv const&);
} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
Consider the following C++ code:
#include <string>
struct A {
A(const std::string& s): s(s) {}
std::string s;
};
struct B: A {
using A::A;
};
int main() {
B b("test");
}
When I compile it via GCC 6.2.1 with the -Wuseless-cast parameter
g++ -std=c++14 -Wuseless-cast test.cpp -o test
it emits the following warning:
test.cpp: In constructor ‘B::B(const string&)’:
test.cpp:9:14: warning: useless cast to type ‘const string& {aka const std::__cxx11::basic_string<char>&}’ [-Wuseless-cast]
using A::A;
^
test.cpp: In function ‘int main()’:
test.cpp:13:15: note: synthesized method ‘B::B(const string&)’ first required here
B b("test");
^
However, when I change the definition of B to
struct B: A {
B(const std::string& s): A(s) {}
};
the warning goes away.
Questions:
Why is the warning emitted?
Why does specifying a constructor for B instead of inheriting it from A fixes the warning?
Your example can be further reduced to:
struct A {
A(const int& i): i(i) {}
int i;
};
struct B: A {
using A::A;
};
int main() {
B b(0);
}
That is an open issue on GCC.
Including <string> isn't apparently required to reproduce it.
Note that the issue is still unconfirmed and it is known to affect at least GCC 6.1 - by looking at your question I would say that it affects also GCC 6.2.
You are probably facing a known GCC bug (PR 70844).
I have this piece of code that compiles fine with clang (even with -Weverything), but for which gcc issues an error.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
class PhonebookWriter
{
public:
PhonebookWriter(const string& fname):
fname_(fname), names_(), numbers_() {}
PhonebookWriter& operator()(const string& name,
const string& number)
{
names_.push_back(name);
numbers_.push_back(number);
return *this;
}
~PhonebookWriter(void)
{
ofstream f(fname_.c_str());
for(size_t i=0;i<names_.size();++i)
f << names_[i] << " " << numbers_[i] << "\n";
f.close();
}
private:
const string fname_;
vector<string> names_;
vector<string> numbers_;
};
namespace {
void write_guests_data(const string& fname)
{
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
}
}
int main(void)
{
write_guests_data("phone_book.txt");
return 0;
}
and here's what I get when I try to compile the code:
$ g++ ./test.cpp
./test.cpp: In function ‘void {anonymous}::write_guests_data(const string&)’:
./test.cpp:39:27: error: declaration of ‘PhonebookWriter fname’ shadows a parameter
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
^
./test.cpp:39:48: error: no matching function for call to ‘PhonebookWriter::PhonebookWriter(const char [11], const char [6])’
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
^
./test.cpp:39:48: note: candidates are:
./test.cpp:11:3: note: PhonebookWriter::PhonebookWriter(const string&)
PhonebookWriter(const string& fname):
^
./test.cpp:11:3: note: candidate expects 1 argument, 2 provided
./test.cpp:7:7: note: PhonebookWriter::PhonebookWriter(const PhonebookWriter&)
class PhonebookWriter
^
./test.cpp:7:7: note: candidate expects 1 argument, 2 provided
./test.cpp:39:49: error: expected ‘,’ or ‘;’ before ‘(’ token
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
^
My gcc version is 4.9.1, and my clang version is 3.5.0.
I don't understand why there should even be a shadowing problem. Even if there were, it should have been picked up by clang.
Change:
PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
to:
(PhonebookWriter(fname))("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
EXPLANATION
For some reason gcc removes the braces around fname, which turns the line into:
PhonebookWriter fname ("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
And now the errors make sense.
using namespace std;
#ifdef DEBUG
#define debug(args...) {dbg,args; cerr<<endl;}
#else
#define debug(args...) // Just strip off all debug tokens
#endif
struct debugger
{
template<typename T> debugger& operator , (const T& v)
{
cerr<<v<<" ";
return *this;
}
} dbg;
int main(){
int a=1,b=2,c=3;
debugger(a,b,c);
}
I found this debug macro and I am trying to use this but this isn't working. I am getting following error:
ubuntu:~ g++ -DEBUG a.cpp -o a
a.cpp: In function ‘int main()’:
a.cpp:81:16: error: no matching function for call to ‘debugger::debugger(int&, int&, int&)’
a.cpp:81:16: note: candidates are:
a.cpp:62:8: note: debugger::debugger()
a.cpp:62:8: note: candidate expects 0 arguments, 3 provided
a.cpp:62:8: note: debugger::debugger(const debugger&)
a.cpp:62:8: note: candidate expects 1 argument, 3 provided
You can simply try by using:-
debug(a, b, c);
Also you have to change the command line -DDEBUG -- the -D is "define". Presently you're defining "EBUG".