Whats wrong with passing gcc vector::iterator to a function? - gcc

This compiles fine in MSVC but gcc complains. The code on ideone. I don't understand what is wrong by passing the iterators by reference.
The error
prog.cpp: In function ‘void FindType()’:
prog.cpp:8: error: no matching function for call to ‘FindType(__gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >, __gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >)’
prog.cpp:4: note: candidates are: void FindType(__gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >&, __gnu_cxx::__normal_iterator<Var**, std::vector<Var*, std::allocator<Var*> > >&)
prog.cpp:5: note: void FindType()
prog.cpp:8: error: return-statement with a value, in function returning 'void'
The code
#include <vector>
using namespace std;
class Var {};
void FindType(vector<Var*>::iterator&b, vector<Var*>::iterator&e){}
void FindType()
{
vector<Var*> ls;
return FindType(ls.begin(), ls.end());
}

Pass const references. The .begin() and .end() calls return rvalues.
Revision: However, as you have observed in the comments below, you cannot do ++b if b is a const reference. Your idea below seems best in that case: pass that iterator by value.

Related

how to report grammar ambiguity in antlr4 with c++ target

This question is a followup on a similar question with java code - how-to-report-grammar-ambiguity-in-antlr4. I am trying to port that code to c++, but I am facing some compilation errors with using the antlr templates.
The main program in c++ is the following:
// TestA_Main.cpp
using namespace std;
using namespace antlr4;
using namespace atn;
int main(int argc, char **argv)
{
string filename = argv[0];
ifstream stream;
stream.open(filename);
ANTLRInputStream input(stream);
AmbigLexer lexer(&input);
CommonTokenStream tokens(&lexer);
AmbigParser parser(&tokens);
parser.addErrorListener(new DiagnosticErrorListener());
// the following line has an error on the call to getInterpreter
parser.getInterpreter().setPredictionMode(PredictionMode::LL_EXACT_AMBIG_DETECTION);
parser.stat();
}
I ran the following commands on it:
java org.antlr.v4.Tool -Dlanguage=Cpp Ambig.g4
g++ -std=gnu++0x -I. -I/antlr4_cpp/runtime/include -I/antlr4_cpp/runtime/include/atn TestA_Main.cpp
And I am getting the following compilation errors, on the call to getInterpreter:
TestA_Main.cpp: In function ‘int main(int, char**)’:
TestA_Main.cpp:27:27: error: no matching function for call to ‘AmbigParser::getInterpreter()’
parser.getInterpreter().setPredictionMode(PredictionMode::LL_EXACT_AMBIG_DETECTION);
^
In file included from /softwares/antlr4/antlr4_cpp/runtime/include/Lexer.h:8:0,
from /softwares/antlr4/antlr4_cpp/runtime/include/antlr4-runtime.h:32,
from TestA_Main.cpp:4:
/softwares/antlr4/antlr4_cpp/runtime/include/Recognizer.h:73:8: note: candidate: template<class T> T* antlr4::Recognizer::getInterpreter() const
T* getInterpreter() const {
^
/softwares/antlr4/antlr4_cpp/runtime/include/Recognizer.h:73:8: note: template argument deduction/substitution failed:
TestA_Main.cpp:27:27: note: couldn't deduce template parameter ‘T’
parser.getInterpreter().setPredictionMode(PredictionMode::LL_EXACT_AMBIG_DETECTION);
Can you please tell me how to fix the above code? I am using antlr-4.6
It's a template function and you have to specify the template parameter explicitly:
parser.getInterpreter<ParserATNSimulator>()->setPredictionMode(PredictionMode::SLL);

No member named value in std::is_convertible when using clang

In a very simple situation with a constrained constructor, testing for convertibility of the argument, an error is produced in clang, but not in g++:
#include <type_traits>
template <class T, class U>
constexpr bool Convertible = std::is_convertible<T,U>::value && std::is_convertible<U,T>::value;
template <class T>
struct A
{
template <class S, class = std::enable_if_t<Convertible<S,T>> >
A(S const&) {}
};
int main()
{
A<double> s = 1.0;
}
Maybe this issue is related to Is clang's c++11 support reliable?
The error clang gives, reads:
error: no member named 'value' in 'std::is_convertible<double, A<double> >'
constexpr bool Convertible = std::is_convertible<T,U>::value && std::is_convertible<U,T>::value;
~~~~~~~~~~~~~~~~~~~~~~~~~~^
I've tried
g++-5.4, g++-6.2 (no error)
clang++-3.5, clang++-3.8, clang++-3.9 (error)
with argument -std=c++1y and for clang either with -stdlib=libstdc++ or -stdlib=libc++.
Which compiler is correct? Is it a bug in clang or gcc? Or is the behavior for some reasons undefined and thus both compilers correct?
First of all, note that it works fine if you use:
A<double> s{1.0};
Instead, the error comes from the fact that you are doing this:
A<double> s = 1.0;
Consider the line below (extracted from the definition of Convertible):
std::is_convertible<U,T>::value
In your case, this is seen as it follows (once substitution has been performed):
std::is_convertible<double, A<double>>::value
The compiler says this clearly in the error message.
This is because a temporary A<double> is constructed from 1.0, then it is assigned to s.
Note that in your class template you have defined a (more or less) catch-all constructor, so a const A<double> & is accepted as well.
Moreover, remember that a temporary binds to a const reference.
That said, the error happens because in the context of the std::enable_if_t we have that A<double> is an incomplete type and from the standard we have this for std::is_convertible:
From and To shall be complete types [...]
See here for the working draft.
Because of that, I would say that it's an undefined behavior.
As a suggestion, you don't need to use std::enable_if_t in this case.
You don't have a set of functions from which to pick the best one up in your example.
A static_assert is just fine and error messages are nicer:
template <class S>
A(S const&) { static_assert(Convertible<S,T>, "!"); }

Confusing clang error attempting to instantiate std::thread with a pointer

While looking at Thread and interfaces C++, I noticed something a little strange with my Clang.
I have c++ --version output of
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
Compiling the following
#include <thread>
class Foo {
public:
void operator()() { }
};
int main() {
Foo *foo = new Foo();
std::thread t(foo);
t.join();
delete foo;
}
with c++ thread.cpp yields the following sensible error:
In file included from thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:369:5: error: called object type 'Foo *' is not a function or
function pointer
(*__p)();
^~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:377:42: note: in instantiation of function template
specialization 'std::__1::__thread_proxy<Foo *>' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get());
^
thread.cpp:10:17: note: in instantiation of function template specialization 'std::__1::thread::thread<Foo *>' requested here
std::thread t(foo);
^
1 error generated.
Total sense - Foo * isn't a function pointer.
But, compiling it with c++ -std=c++11 thread.cpp gives this cryptic error:
In file included from thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:332:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:342:5: note: in instantiation of function template
specialization 'std::__1::__thread_execute<Foo *>' requested here
__thread_execute(*__p, _Index());
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:354:42: note: in instantiation of function template
specialization 'std::__1::__thread_proxy<std::__1::tuple<Foo *> >' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
^
thread.cpp:10:17: note: in instantiation of function template specialization 'std::__1::thread::thread<Foo *&, void>' requested here
std::thread t(foo);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/type_traits:1027:5: note: '~__nat' has been explicitly marked
deleted here
~__nat() = delete;
^
1 error generated.
What's causing this weird error message about a deleted destructor? Should I consider it a bug in Clang to have such an odd message?
Your actual error message is the same in the two cases: whatever template is used to implement std::thread, it cannot be specialized for Foo*.
~__nat() = delete; is only a random difference between the old and new standard, one of the uninteresting things that fail because of the type error.

C++11 static assertion fails noexcept check with Clang++?

I'm trying to compile the following code with clang++ -std=c++11 -c and it fails:
void g() noexcept {}
template <typename Func>
void f(Func && func) noexcept(noexcept(func()))
{ static_assert(noexcept(func()), "func()"); } // No error!
void h() { f(&g); } // No error!
static_assert(noexcept(f(&g)), "Error!");
The error message Clang 3.4.2 gives me is:
test.h:9:1: error: static_assert failed "Error!"
static_assert(noexcept(f(&g)), "Error!");
^ ~~~~~~~~~~~~~~~
What am I missing here?
noexcept is not a part of a function type.
Thus, &g is just your run of the mill expression of type void(*)(), with no special noexcept powers. So is g, as it decays to the function pointer. When such a function pointer is eventually called, it has no noexcept specification, and thus the entire expression is not noexcept.

no matching function for call to 'lower_bound' with newer gcc

I'm having some trouble compiling code that uses std::lower_bound on systems with newer versions of gcc. From my tests, 4.1 works, but 4.6 fails.
Here is the relevant code snippet:
template <typename RandomAccessIterator, typename Value, typename Comparer>
int my_binary_search(RandomAccessIterator const first, RandomAccessIterator const last, Value const& value, Comparer comparer)
{
RandomAccessIterator it(std::lower_bound(first, last, value, comparer));
//some more code below
}
The error I am seeing is:
error: no matching function for call to ‘lower_bound(const __gnu_cxx::__normal_iterator<int*, std::vector<int> >&, const __gnu_cxx::__normal_iterator<int*, std::vector<int> >&, const int&, bool (*&)(int, int))’
testing.h:37:75: note: candidate is:
/usr/include/c++/4.6/bits/stl_algobase.h:936:5: note: template<class _ForwardIterator, class _Tp> _ForwardIterator std::lower_bound(_ForwardIterator, _ForwardIterator, const _Tp&)
Does anybody have ideas on how to fix this?
For anyone finding this on google:
I had the same issue
Includes were "functional" and "list", didnt give me any error lower_bound wasnt defined or anything, just that it couldnt find a matching function.
Including "algorithm" did the trick.. nearly an hour of searching around for such a stupid thing

Resources