gmp_int Boost errors - c++

Here is my simple test code:
#include <boost/multiprecision/gmp.hpp>
using namespace boost::multiprecision;
int main()
{
gmp_int v = 1;
std::cout << v << std::endl;
return 0;
}
When I try to build and run, I get the following errors:
error: there are no arguments to 'mp_get_memory_functions' that depend on a template parameter, so a declaration of 'mp_get_memory_functions' must be available [-fpermissive]
note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
error: 'mp_get_memory_functions' was not declared in this scope
error: 'mpz_combit' was not declared in this scope
error: 'mp_get_memory_functions' was not declared in this scope|
error: invalid conversion from 'int' to 'const __mpz_struct*' [-fpermissive]
error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = boost::multiprecision::backends::gmp_int]'
I am using Code::Blocks. I used precompiled GMP libraries for windows. In code::Blocks I have gmp\lib\libgmp.ain the linker, gmp\include in compiler directories and gmp\lib in linker directories.
Any help would be appreciated in getting GMP to work. I think that I did not install GMP correctly, but it might be a simple issue.

You forgot to use a number adaptor with your gmp_int backend type:
number<gmp_int> v = 1;
See it Live On Coliru:
#include <boost/multiprecision/gmp.hpp>
#include <iostream>
using namespace boost::multiprecision;
int main()
{
number<gmp_int> v = 1;
std::cout << v << std::endl;
}

I have solved the issue. I was not linking all my header and library files correctly.

Related

"In instantiation of ... required ... required from here" and "no type named..." in std::stable_sort

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string TmpS;
cin >> TmpS;
stable_sort(TmpS[0], TmpS[TmpS.size()]);
}
Compiling this code on Compiler Explorer gives me these following errors:
In file included from /opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/algorithm:62,
from <source>:2:
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h: In instantiation of 'void std::__stable_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = char; _Compare = __gnu_cxx::__ops::_Iter_less_iter]':
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h:5056:36: required from 'void std::stable_sort(_RAIter, _RAIter) [with _RAIter = char]'
<source>:8:16: required from here
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h:5008:9: error: no type named 'value_type' in 'struct std::iterator_traits<char>'
5008 | _ValueType;
| ^~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h:5010:9: error: no type named 'difference_type' in 'struct std::iterator_traits<char>'
5010 | _DistanceType;
| ^~~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.1.0/include/c++/11.1.0/bits/stl_algo.h:5011:68: error: no type named 'value_type' in 'struct std::iterator_traits<char>'
5011 | typedef _Temporary_buffer<_RandomAccessIterator, _ValueType> _TmpBuf;
| ^~~~~~~
I don't understand these errors, presumably it's failing at deducing what type the values and range should be? Googling did not help. Why does the compiler throw these errors and how do I fix my code?
You want std::sort(TmpS.begin(), TmpS.end());.
std::stable_sort(TmpS.begin(), TmpS.end()); would also work, but because you don't provide a custom comparator, it would do the exact same thing as std::sort, while being slower (because of the stability guarantee).
You need to pass the iterators of the start and end point of the string.(To be precise the portion of the string you want to sort)
So you can use begin() and end() methods here
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
string TmpS;
cin >> TmpS;
stable_sort(TmpS.begin(), TmpS.end());
cout << TmpS;
}
You need to pass references to the data, not the values themselves.
stable_sort(&TmpS[0], &TmpS[TmpS.size()]);

C++ map invalid conversion from int to const LexType& (which is defined by myself in fact a int)

I defined a map like this :
std::map<std::string,LexType> lexname_s = { { "PROGRAM" , PROGRAM}}
And a LexType, like this :
typedef enum
{
ENDFILE, ERROR,
PROGRAM, PROCEDURE, TYPE, VAR, IF,
} LexType;
In Visual Studio Code, it always shows error type when I touch it.
//
I add more details for what i said.
the line
std::map<std::string,LexType> lexname_s = { { "PROGRAM" , PROGRAM}}
show error . it seems i can't initialize it in this way.
I compile it in the gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) in a cloud server which is centos7.
AND the error code shows below
from parse.cpp:1:
../utils.h:52:27: error: invalid conversion from ‘int’ to ‘const LexType&’ [-fpermissive]
{"ERROR", ERROR}};
^
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8.2/bits/stl_tree.h:61,
from /usr/include/c++/4.8.2/map:60,
from ../globals.h:6,
from parse.h:4,
from parse.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:112:26: error: initializing argument 2 of ‘constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) [with _T1 = const std::basic_string<char>; _T2 = LexType]’ [-fpermissive]
_GLIBCXX_CONSTEXPR pair(const _T1& __a, const _T2& __b)```
EOF(which shows in the map define) is a reserved a macro defined in stdio.h
it's the problem of it.
change the name will be ok.

Why does this use of boost::none fail to compile with nvcc?

I'm trying to compile the following code:
#include <boost/optional.hpp>
void foo(boost::optional<unsigned> x = boost::none);
placed in the file a.cu, with the CUDA compiler, using the following command line:
nvcc a.cu -c --std=c++11 -I/opt/boost/include
but I get a bunch of errors:
a.cu:2:53: error: conversion from ‘const boost::none_t(boost::none_t::init_tag (*)())’ to ‘boost::optional<unsigned int>’ is ambiguous
void foo(boost::optional<unsigned> x = boost::none);
^
/opt/boost/include/boost/optional/optional.hpp:805:1: note: candidate: boost::optional<T>::optional(boost::optional<T>::rval_reference_type) [with T = unsigned int; boost::optional<T>::rval_reference_type = unsigned int&&] <near match>
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
^ ~~~~
/opt/boost/include/boost/optional/optional.hpp:805:1: note: conversion of argument 1 would be ill-formed:
a.cu:2:53: error: invalid conversion from ‘const boost::none_t (*)(boost::none_t::init_tag (*)())’ to ‘unsigned int’ [-fpermissive]
void foo(boost::optional<unsigned> x = boost::none);
^
/opt/boost/include/boost/optional/optional.hpp:800:1: note: candidate: boost::optional<T>::optional(boost::optional<T>::argument_type) [with T = unsigned int; boost::optional<T>::argument_type = const unsigned int&] <near match>
optional ( argument_type val ) : base(val) {}
^ ~~~~
/opt/boost/include/boost/optional/optional.hpp:800:1: note: conversion of argument 1 would be ill-formed:
a.cu:2:53: error: invalid conversion from ‘const boost::none_t (*)(boost::none_t::init_tag (*)())’ to ‘unsigned int’ [-fpermissive]
void foo(boost::optional<unsigned> x = boost::none);
Why does this happen, and can I circumvent the problem while still actually using boost::optional in (host-side) code compiled with nvcc?
Additional information:
The code compiles fine with g++ 6.3.0 (my distribution's compiler).
This code (or rather, similar code) used to compile and work on an earlier Linux distribution I was using, where the compiler was g++ 5.4.x .
I've tried this with Boost versions 1.65.1 and 1.69.0 .
I've tried this with CUDA versions 9.2.88 and 10.0.130 .
I had the exact same error and was able to get this to work with this modification:
#define BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
#include <boost/optional.hpp>
This is using CUDA 10.0.130, g++ 7.3.0, and Boost 1.68.0.
A partial answer to the second question:
You could consider using Andrzej Krzemieński's neat and self-contained implementation of an optional instead of boost::optional. It works with C++11, which is what you seem to be doing.

Shortening GCC error messages

Whenever gcc can't find a matching overload for a function with multiple overloads, it gives lines and lines of errors, explaining which overload was tried and why it was not used.
While often it is useful, it is also often not, as the problem as a simple typo at the call site. And in this particular case, it is not even helpful, because it will take considerable time to even find out which line is ultimately responsible for this issue.
Is there any command line switch to GCC to shorten the output and only include the actual triggering line? For example:
#include <string>
#include <iostream>
struct Z{};
void foo() {
std::string s;
Z z;
std::cout << z; // typo - meant s
}
See error output: https://godbolt.org/g/wz5vL2
Small addition: third party solutions (STLFilt, gccfilter, etc) do not fit the bill, because a) my work environment is not welcoming towards installing 3rd party apps and b) they tend to become unmaintained and stop working with the next compiler upgrade
One way is to use -Wfatal-errors. It changes the error message from
<source>: In function 'void foo()':
<source>:11:15: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Z')
std::cout << z; // typo - meant s
~~~~~~~~~~^~~~
In file included from /opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/iostream:39:0,
from <source>:2:
/opt/compiler-explorer/gcc-7.3.0/include/c++/7.3.0/ostream:108:7: note: candidate: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
operator<<(__ostream_type& (*__pf)(__ostream_type&))
many more lines of errors
to
<source>: In function 'void foo()':
<source>:11:15: error: no match for 'operator<<' (operand types are 'std::ostream {aka std::basic_ostream<char>}' and 'Z')
std::cout << z; // typo - meant s
~~~~~~~~~~^~~~
compilation terminated due to -Wfatal-errors.
Compiler returned: 1
The only downside is you will only get the first error. If your compile times are long then this isn't the greatest as you wouldn't be able to fix any other errors until you fix that first one and recompile.

C++ writing to file error in Linux/Ubuntu?

I have been trying to learn C++ recently, but I have stumbled across some errors. For example, when I try to run this code to ask the user what they want outputted to a file:
#include <iostream>
#include <cstdio>
using namespace std;
main() {
string output; //Declare variables before starting
FILE * file = fopen("newfile.txt","w"); //creates file
cout << "Entire something that you want to be written to the file: " << endl;
cin.getline(output, 256); //Asks what you want to put into file
fprintf(file, output); //Puts output into file
fclose(file); //closes file
return 0;
}
using
g++ -o main test.cpp
I get this error:
test.cpp: In function ‘int main()’:
test.cpp:10:25: error: no matching function for call to ‘std::basic_istream<char>::getline(std::string&, int)’
cin.getline(output, 256);
^
test.cpp:10:25: note: candidates are:
In file included from /usr/include/c++/4.8/iostream:40:0,
from test.cpp:1:
/usr/include/c++/4.8/istream:618:5: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::getline(std::basic_istream<_CharT, _Traits>::char_type*, std::streamsize, std::basic_istream<_CharT, _Traits>::char_type) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::char_type = char; std::streamsize = long int]
basic_istream<char>::
^
/usr/include/c++/4.8/istream:618:5: note: candidate expects 3 arguments, 2 provided
/usr/include/c++/4.8/istream:427:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::getline(std::basic_istream<_CharT, _Traits>::char_type*, std::streamsize) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>; std::basic_istream<_CharT, _Traits>::char_type = char; std::streamsize = long int]
getline(char_type* __s, streamsize __n)
^
/usr/include/c++/4.8/istream:427:7: note: no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘std::basic_istream<char>::char_type* {aka char*}’
test.cpp:11:22: error: cannot convert ‘std::string {aka std::basic_string<char>}’ to ‘const char*’ for argument ‘2’ to ‘int fprintf(FILE*, const char*, ...)’
fprintf(file, output);
^
Could someone please help me? And please forgive me if this is something that can be easily solved, I am fairly new to C++ and do not quite understand it yet.
The header for string is missing:
#include <string>
Without it, sring isn't defined, and everywhere you use output, you'll have errors
With the include you'll have a lot less errors. But this line has another issue (as πάντα ῥεῖ already pointed out):
cin.getline(output, 256);
because cin.getline() expects a char* and the length. If you want to use a string, you have to use the function getline(), without size (limited to strings maximume size) and on an istream:
getline(cin, output);
Last remark: you are of course free to mix c-style io and streams. But you could win from getting used to streams for all your file io.
The error occurs at the line
cin.getline(output, 256);
According to the documentation for std::istream::getline, the first argument for cin.getline() should be a char * and not a std::string as you have declared it.
Try changing the declaration of output to a char * like so
char[256] output;
Edit: Using std::getline as the others have said would be a better idea though.