std::hash for __uint128_t - c++

I am facing an issue hashing __uint128_t. Following is my code:
#include <iostream>
int main () {
__uint128_t var = 1;
std::cout << std::hash<__uint128_t> () (var) << "\n";
return 0;
}
I am getting the error as:
test.cpp: In function ‘int main()’:
test.cpp:5:40: error: use of deleted function ‘std::hash<__int128 unsigned>::hash()’
5 | size_t h = std::hash<__uint128_t> () (var);
| ^
How can I get the hash for __uint128_t? (Probably a very basic question but I have been stuck here for a while). Also, I would like to know the meaning of the error. Thanks in advance.

Taking a look at the docs on https://en.cppreference.com/w/cpp/utility/hash. You will have to write your own.
Here is some code for what a basic __uint128_t hash function might look like:
namespace std {
template<>
struct hash<__uint128_t> {
size_t operator()(__uint128_t var) const {
return std::hash<uint64_t>{}((uint64_t)var ^ (uint64_t)(var >> 64));
}
};
}
Note not tested or compiled.

Related

How to iterate through a range-based for loop when the data type of the array is const char *?

I am trying to solve the following question:
https://www.codewars.com/kata/54bf1c2cd5b56cc47f0007a1/train/cpp in C++.
When I try to iterate over a range based for loop I get the following error ->
In file included from main.cpp:6:
./solution.cpp:14:13: error: invalid range expression of type 'const char *'; no viable 'begin' function available
for(auto x: in){
^ ~~
1 error generated.
The code ->
Also , further on I am also encountering an error while comparing, if(x!=' ') that I am comparing wrong data types, I am trying to understand the dereferencing concept and its escaping my understanding. can someone break down the explanation for me please?
#include <unordered_map>
#include <string.h>
using namespace std;
size_t duplicateCount(const std::string& in); // helper for tests
size_t duplicateCount(const char* in)
{
unordered_map<char , int> hash;
for(auto x: in){
cout<<"char:"<<x<<endl;
if(hash[x]>=0){
hash[x]+=1;
} else {
if(x!=" "){
hash[x]=0;
}
}
}
int ct=0;
for(auto x:hash){
if(x.second>1){
ct++;
}
}
return ct;
}
You just can't use range based for loops with plain old arrays. In your case you could use std::string_view as a wrapper around your char array:
const char* in = "hallo welt";
std::string_view sv(in);
for(const auto& x: sv){
std::cout<<"char:"<<x<<std::endl;
if(x == 'h')
std::cout<<"h-detected"<<std::endl;
}

How to fix "error: call to 'abs' is ambiguous"

I'm running a simple C++ program from HackerRank about pointers and it works fine on the website. However,
when I run it on MacOS, I get error: call to 'abs' is ambiguous and I'm not sure exactly what is ambiguous.
I've looked at other answers to similar issues, but the error message tends to be Ambiguous overload call to abs(double), which is not the issue I'm having, since I haven't used any doubles. I've also tried including the header files cmath and math.h, but the problem persists.
#include <stdio.h>
#include <cmath>
void update(int *a,int *b) {
int num1 = *a;
int num2 = *b;
*a = num1 + num2;
*b = abs(num1 - num2);
}
int main() {
int a, b;
int *pa = &a, *pb = &b;
scanf("%d %d", &a, &b);
update(pa, pb);
printf("%d\n%d", a, b);
return 0;
}
My issue occurs with line 8.
The full error message is:
$ clang++ test.cpp
test.cpp:8:10: error: call to 'abs' is ambiguous
*b = abs(num1 - num2);
^~~
.../include/c++/v1/math.h:769:1: note: candidate function
abs(float __lcpp_x) _NOEXCEPT {return ::fabsf(__lcpp_x);}
^
.../include/c++/v1/math.h:769:1: note: candidate function
abs(double __lcpp_x) _NOEXCEPT {return ::fabs(__lcpp_x);}
^
.../include/c++/v1/math.h:769:1: note: candidate function
abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
^
1 error generated.
The three overloads of abs that you have from <cmath> are abs(float), abs(double) and abs(long double); it's ambiguous because you have an int argument and the compiler doesn't know which floating-point type to convert to.
abs(int) is defined in <cstdlib>, so #include <cstdlib> will resolve your problem.
If you're using Xcode, you can get more details about the error in the Issues navigator (⌘5) and clicking the triangle next to your issue.
For me, #include <cstdlib> didn't solve the issue, maybe because I didn't have to include anything to use abs. So, in case it helps someone else, with explicit casting, it worked well for me like in the next code:
*b = abs(int(num1 - num2));
In templated code, it may be easily overlooked that std::abs is not defined for unsigned types. As an example, if the following method is instantiated for an unsigned type, the compiler may rightfully complain that std::abs is undefined:
template<typename T>
bool areClose(const T& left, const T& right) {
// This is bad because for unsigned T, std::abs is undefined
// and for integral T, we compare with a float instead of
// comparing for equality:
return (std::abs(left - right) < 1e-7);
}
int main() {
uint32_t vLeft = 17;
uint32_t vRight = 18;
std::cout << "Are the values close? " << areClose(vLeft, vRight) << std::endl;
}
A better definition of areClose() in above code, that would coincidentally also solve the problem of std::abs() being undefined, could look like this:
template<typename T>
bool areClose(const T& left, const T& right) {
// This is better: compare all integral values for equality:
if constexpr (std::is_integral<T>::value) {
return (left == right);
} else {
return (std::abs(left - right) < 1e-7);
}
}
if your using C compiler you should include
#include <stdlib.h>
and use abs without std::.
If you use C++ compiler then you should change abs to std::abs.
Hope it helps:)
I used #include <bits/stdc++.h> as the only include statement and it worked for me.
My code:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<int> findDuplicates(vector<int>& nums) {
int n = nums.size();
if(n == 0 || n == 1)
return {};
vector<int> ans;
for(int i = 0; i < n; i++)
{
if(nums[abs(nums[i])-1] < 0)
ans.push_back(abs(nums[i]));
else
nums[abs(nums[i])-1] = -1 * nums[abs(nums[i])-1];
}
return ans;
}
};

C++ Error: no matching function for call to ‘simplex615<arbitraryFunc>::amoeba

I'm trying to implement some C++ code to find the maximum of a function using a simplex algoithm. Unfortunately, I have zero experience in C++.
I'm running into this error and can't seem to find a solution from answers to similar questions.
simplex.cpp: In function ‘int main(int, char**)’:
simplex.cpp:22:25: error: no matching function for call to
‘simplex615::amoeba(arbitraryFunc&, double)’
simplex.amoeba(foo, 1e-7);
There is also warning related to the linked file "simplex615.h"
In file included from simplex.cpp:4:0:
simplex615.h:302:6: note: candidate: void simplex615::amoeba(optFunc&, double) [with F = arbitraryFunc]
void simplex615 ::amoeba(optFunc& foo, double tol) {
simplex615.h:302:6: note: no known conversion for argument 1 from ‘arbitraryFunc’ to ‘optFunc&
simplex.cpp
#include <vector>
#include <cmath>
#include <iostream>
#include "simplex615.h"
#define ZEPS 1e-10
// function object used as an argument
class arbitraryFunc {
public:
double operator() (std::vector<double>& x) {
// f(x0,x1) = 100*(x1-x0^2)^2 + (1-x0)^2
return 100*(x[1]-x[0]*x[0])*(x[1]-x[0]*x[0])+(1-x[0])*(1-x[0]);
}
};
int main(int main, char** argv) {
double point[2] = {-1.2, 1};
arbitraryFunc foo;
// initial point to start
// WILL BE DISCUSSED LATER
simplex615 <arbitraryFunc> simplex(point, 2); // create a simplex
simplex.amoeba(foo, 1e-7); // optimize for a function
// print outputs
std::cout << "Minimum = " << simplex.ymin() << ", at ("
<< simplex.xmin()[0] << ", " << simplex.xmin()[1]
<< ")" << std::endl;
return 0;
}
simplex615.h
template <class F> // F is a function object
void simplex615 <F>::amoeba(optFunc& foo, double tol) {
evaluateFunction(foo);
while(true) {
evaluateExtremes();
prepareUpdate();
if ( check_tol(Y[idxHi],Y[idxLo],tol) ) break;
updateSimplex(foo, -1.0); // reflection
if ( Y[idxHi] < Y[idxLo] ) {
updateSimplex(foo, -2.0); // expansion
}
else if ( Y[idxHi] >= Y[idxNextHi] ) {
if ( !updateSimplex(foo, 0.5) ) {
contractSimplex(foo);
}
}
}
}
simplex615.h
class optFunc {
public:
virtual double operator() (std::vector<double>& x) = 0;
};
Link to the complete files simplex.cpp and simplex.h: Source code
Any help will be appreciated. Thanks.
It seems to me that in your simplex615.h you have forgotten to use 'class F' in amoeba method. Just replace optFunc with F and it should fix the problem.
template <class F> // F is a function object
void simplex615 <F>::amoeba(F& foo, double tol) {
...
}
A template class argument in C++ defines a general type which can be replaced when using the template.
Also from this example, you can remove the declaration of optFunc from the header file.

c++ struct and "expected primary-expression" error

It's easier to explain with some code:
#include <iostream>
using namespace std;
struct test {
int one;
int two;
};
void insertdata(test & info)
{
cin >> info.one;
cin >> info.two;
}
int doitnow(test mytable[])
{
test info;
int i = 0;
for (i=0; i<3; i++) {
insertdata(test & info);
mytable[i] = info;
}
return i;
}
int main()
{
int total;
test mytable[10];
total = doitnow(test mytable[]);
cout << total;
}
So, I need to pass info by reference to the function insertdata, I need to use that function in doitnow to fill up a table and I need to show in the main function the number of items inserted in doitnow. I keep getting errors when I try to call functions:
teste.cpp: In function ‘int doitnow(test*)’:
teste.cpp:21:29: error: expected primary-expression before ‘&’ token
insertdata(test & info);
teste.cpp: In function ‘int main()’:
teste.cpp:33:30: error: expected primary-expression before ‘mytable’
total = doitnow(test mytable[]);
So, probably it's an obvious mistake but I'm a beginner at this.
Thanks for your help.
test& info is a definition. If you pass something to a function, you write an expression like info. It is automatically passed by reference because you specified info as a reference in the formal parameter list.
You also wrote
mytable[i] = info;
and not
mytable[i] = test & info;
didn't ya?
Use insertdata(info); instead.
Same goes for arrays. Use doitnow(test) instead.

How to fix C++ error: expected unqualified-id

I'm getting this error on line 6:
error: expected unqualified-id before '{' token
I can't tell what's wrong.
#include <iostream>
using namespace std;
class WordGame;
{ // <== error is here on line 6
public:
void setWord( string word )
{
theWord = word;
}
string getWord()
{
return theWord;
}
void displayWord()
{
cout << "Your word is " << getWord() << endl;
}
private:
string theWord;
}
int main()
{
string aWord;
WordGame theGame;
cin >> aWord;
theGame.setWord(aWord);
theGame.displaymessage();
}
There should be no semicolon here:
class WordGame;
...but there should be one at the end of your class definition:
...
private:
string theWord;
}; // <-- Semicolon should be at the end of your class definition
As a side note, consider passing strings in setWord() as const references to avoid excess copying. Also, in displayWord, consider making this a const function to follow const-correctness.
void setWord(const std::string& word) {
theWord = word;
}
Get rid of the semicolon after WordGame.
You really should have discovered this problem when the class was a lot smaller. When you're writing code, you should be compiling about every time you add half a dozen lines.
Semicolon should be at the end of the class definition rather than after the name:
class WordGame
{
};
For what it's worth, I had the same problem but it wasn't because of an extra semicolon, it was because I'd forgotten a semicolon on the previous statement.
My situation was something like
mynamespace::MyObject otherObject
for (const auto& element: otherObject.myVector) {
// execute arbitrary code on element
//...
//...
}
From this code, my compiler kept telling me:
error: expected unqualified-id before for (const auto& element: otherObject.myVector) {
etc...
which I'd taken to mean I'd writtten the for loop wrong. Nope! I'd simply forgotten a ; after declaring otherObject.
For anyone with this situation: I saw this error when I accidentally used my_first_scope::my_second_scope::true in place of simply true, like this:
bool my_var = my_first_scope::my_second_scope::true;
instead of:
bool my_var = true;
This is because I had a macro which caused MY_MACRO(true) to expand into my_first_scope::my_second_scope::true, by mistake, and I was actually calling bool my_var = MY_MACRO(true);.
Here's a quick demo of this type of scoping error:
Program (you can run it online here: https://onlinegdb.com/BkhFBoqUw):
#include <iostream>
#include <cstdio>
namespace my_first_scope
{
namespace my_second_scope
{
} // namespace my_second_scope
} // namespace my_first_scope
int main()
{
printf("Hello World\n");
bool my_var = my_first_scope::my_second_scope::true;
std::cout << my_var << std::endl;
return 0;
}
Output (build error):
main.cpp: In function ‘int main()’:
main.cpp:27:52: error: expected unqualified-id before ‘true’
bool my_var = my_first_scope::my_second_scope::true;
^~~~
Notice the error: error: expected unqualified-id before ‘true’, and where the arrow under the error is pointing. Apparently the "unqualified-id" in my case is the double colon (::) scope operator I have just before true.
When I add in the macro and use it (run this new code here: https://onlinegdb.com/H1eevs58D):
#define MY_MACRO(input) my_first_scope::my_second_scope::input
...
bool my_var = MY_MACRO(true);
I get this new error instead:
main.cpp: In function ‘int main()’:
main.cpp:29:28: error: expected unqualified-id before ‘true’
bool my_var = MY_MACRO(true);
^
main.cpp:16:58: note: in definition of macro ‘MY_MACRO’
#define MY_MACRO(input) my_first_scope::my_second_scope::input
^~~~~
I got this error because I was not declaring a variable and was using it further .
Here is my code why I was getting it.
It was because I was not declaring a variable for size of my >vector.
Just replace
int n=arr.size();
Replace Here,
int sumSubarrayMins(vector<int>& arr) {
int = arr.size();
long long sum;
long long ans =0;
for(long i =0;i<n;i++){
sum =0;
long mini=INT_MAX;
for(long long j =i;j<n;j++){
mini=min(mini,arr[j]);
sum+=mini;
}
ans+=sum;
}
return ans;
}