error: no matching function for call to 'swap' - algorithm

I am trying to sort cakeTypes vector by the size of their weight. But getting the error in sort implementation.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class CakeType
{
public:
const unsigned int weight_;
const unsigned int value_;
CakeType(unsigned int weight = 0, unsigned int value = 0) :
weight_(weight),
value_(value)
{}
};
bool compareCakes(const CakeType& cake1, const CakeType& cake2) {
return cake1.weight_ < cake2.weight_;
}
unsigned long long maxDuffelBagValue(const std::vector<CakeType>& cakeTypes,
unsigned int weightCapacity)
{
// calculate the maximum value that we can carry
unsigned cakeTypesSize = cakeTypes.size();
unsigned long long valueCalculator[weightCapacity+1][cakeTypesSize+1];
for (unsigned int i = 0; i<=weightCapacity+1; i++) {
valueCalculator[i][0] = 0;
}
for (unsigned int i = 0; i<=cakeTypesSize+1; i++) {
valueCalculator[0][i] = 0;
}
vector<CakeType> sortedCakeTypes(cakeTypes);
sort(sortedCakeTypes.begin(), sortedCakeTypes.end(), compareCakes);
return 0;
}
This is part of there error:
exited with non-zero code (1).
In file included from solution.cc:1:
In file included from /usr/include/c++/v1/iostream:38:
In file included from /usr/include/c++/v1/ios:216:
In file included from /usr/include/c++/v1/__locale:15:
In file included from /usr/include/c++/v1/string:439:
/usr/include/c++/v1/algorithm:3856:17: error: no matching function for call to 'swap'
swap(*__first, *__last);
^~~~
I tried this solution sort() - No matching function for call to 'swap', but it is not the same issue.

Data type which is used by swap function in sort algorithm must be MoveAssignable, then you can perform operation like below
CakeType c1, c2;
c1 = move(c2); // <- move c2 to c1
But in your case CakeType has const data members. You can assign values to const data members only in constructors. Code cannot be compiled because default move/copy assignment operator can't be generated by this restriction (assignment to const member is illegal).
Remove const specifier from your class definition and code will work.
class CakeType
{
public:
unsigned int weight_;
unsigned int value_;
CakeType(unsigned int weight = 0, unsigned int value = 0) :
weight_(weight),
value_(value)
{}
};

Related

Arrays declared globally gives out of scope error in functions

I have these arrays declared globally
char str1[] = "6541254939322816220209974565477289648317";
char str2[] = "3142522751761601737419090933147067701840";
int str1_size = strlen(str1);
int str2_size = strlen(str2);
int lcs[str1_size][str2_size];
int arrows[str1_size][str2_size];
But when I access this inside a function, it gives
lcs was not declared in this scope
also
array bound is not an integer constant before ‘]’ token
int lcs[str1_size][str2_size];
What am I doing wrong here ?
First of all
int a[dim];
where dim isn't a compile-time know constant (constexpr by example) isn't C++ standard; maybe it's possible with some extension with some compiler but isn't C++ standard.
So, in your case
int lcs[str1_size][str2_size];
int arrows[str1_size][str2_size];
where str1_size and str2_size are normal (not constexpr, not const initialized with literals) variables, is an error.
If you could redefine str1_size and str2_size as follows
constexpt int str1_size = strlen(str1);
constexpr int str2_size = strlen(str2);
the lcs and arrows definition could works.
Unfortunately (1) str1 and str2 aren't constexpr and (2) std::strlen() isn't constexpr.
But if declare str1/str2 constexpr and write a constexpr alternative to std::strlen...
#include <iostream>
constexpr std::size_t lenStr (char const * str)
{
std::size_t ret{};
while ( *(str++) )
++ret;
return ret;
}
constexpr char str1[] = "6541254939322816220209974565477289648317";
constexpr char str2[] = "3142522751761601737419090933147067701840";
constexpr auto str1_size = lenStr(str1);
constexpr auto str2_size = lenStr(str2);
int lcs[str1_size][str2_size];
int arrows[str1_size][str2_size];
int main ()
{
}
Unfortunately the preceding code require C++14 (in C++11 it's impossible write so complex constexpr functions).
In C++11 you should write lenStr() in a recursive way
constexpr std::size_t lenStr (char const * str, std::size_t ret = 0u)
{ return *str ? lenStr(++str, ++ret) : ret; }

Why isn't the iterator not identifying the datatype of the multi-set in the called function?

I'm trying to find an optimized way to this problem-
https://www.codechef.com/KJCS2019/problems/TSHACK
int findanswer(int k,const multiset<pair<int,int> >&a2)
{
int freq=0;
while(k>0)
{
multiset<pair<int,int> >::iterator itt=a2.end();
k-=itt.second;
a2.erase(itt);
++freq;
}
return freq;
}
int main()
{
cin>>n>>q;
map<int,int>a;
multiset<pair<int,int> > a2;
for(int i=0;i<n;i++)
{
int b;
cin>>b;
++a[b];
}
for(auto it:a)
a2.insert(make_pair(it.second,it.first));
while(q--)
{
int k;
cin>>k;
int ans=findanswer(k,a2);
cout<<ans<<endl;
}
}
the error message :
prog.cpp: In function 'int findanswer(int, const std::multiset<std::pair<int, int> >&)':
prog.cpp:18:16: error: 'std::multiset<std::pair<int, int> >::iterator {aka struct std::_Rb_tree_const_iterator<std::pair<int, int> >}' has no member named 'second'
k-=itt.second;
^
prog.cpp:19:21: error: passing 'const std::multiset<std::pair<int, int> >' as 'this' argument discards qualifiers [-fpermissive]
a2.erase(itt);
^
As I said earlier, I want to know the reason why the iterator in the called function not identifying the datatype of the multiset.
First problem:
You want to access the data which the iterator is pointing to and not the iterator itself. So you simply have to replace:
k-=itt->second;
Next problem:
int findanswer(int k,const multiset<pair<int,int> >&a2)
This defines your ref a2 as const. As const you can't modify your multiset. So you have to remove const here.

There is a way in gcc to get a warning when a constexpr can't be evaluated at compile time?

I'm using gcc 5.1.0 (c++14) and I was trying with constexpr. Is very annoying to verify if the constexpr I've implemented are evaluated at compile time. I couldn't find any flag for get a warning about that situation.
Here is an example:
example.cpp -----------------------------------------
#include <stdlib.h>
const char pruVar[] = "12345678901234567";
[[gnu::noinline]] constexpr unsigned int myStrlen(const char* cstr)
{
unsigned int i=0;
for(;cstr[i]!=0;++i);
return i;
}
struct CEXAMPLE
{
unsigned int size;
constexpr CEXAMPLE(const char* s): size(myStrlen(s))
{
}
};
int main(void)
{
CEXAMPLE c(pruVar);
unsigned int size = myStrlen(pruVar);
void* a = malloc(c.size + size);
if (a != nullptr)
return 0;
else
return 1;
}
In the example CEXAMPLE::CEXAMPLE is evaluated at compile time including the call to myStrlen in it, but the call to myStrlen in main is being evaluated at runtime. The only way I have to know this is looking at the assembler.This website is very useful too: http://gcc.godbolt.org/
If you know how to make the compiler warn about this or something similar I'll appreciate it
myStrlen(pruVar) can be evaluated at compile time; the compiler is just choosing not to in this instance.
If you want to force the compiler to evaluate it at compile time or error if this is not possible, assign the result to a constexpr variable:
constexpr unsigned int size = myStrlen(pruVar);
^^^^^^^^^
You could also use an enum, or a std::integral_constant:
enum : unsigned int { size = myStrlen(pruVar) };
std::integral_constant<unsigned int, myStrlen(pruVar)> size;
Based on the fact that template arguments must be evaluated at compiletime a helper template can be used.
namespace helper {
template<class T, T v> constexpr T enforce_compiletime() {
constexpr T cv = v;
return cv;
}
}
#define compiletime(arg) ::helper::enforce_compiletime<decltype(arg), (arg)>()
This allows compile time enforcement without an additional constexpr variable, which is handy in order to calculate value lookup tables.
constexpr uint32_t bla(uint8_t blub) {
switch (blub) {
case 5:
return 22;
default:
return 23;
}
}
struct SomeStruct {
uint32_t a;
uint32_t b;
};
SomeStruct aStruct = {compiletime(bla(5)), compiletime(bla(6))};

string literal parameter not accepted to a constexpr function

Call to the extract function below does not work for me on g++ 4.9.0 (20130421). The error I get is that s1 is not a constant expression. If i can be initialized as constexpr then j and k should too. Is that wrong?
#include <tuple>
template <unsigned N1, unsigned N2>
constexpr bool strmatch(const char (&s1)[N1], const char (&s2)[N2], unsigned i = 0)
{
return (s1[i]==s2[i]) ?
(s1[i]=='\0') ?
true
: strmatch(s1, s2, i+1)
: false;
}
template<unsigned N>
constexpr int extract(const std::tuple<int, int> & t1, const char (&array)[N]) {
return std::get<strmatch(array, "m0")>(t1);
}
int main(void)
{
constexpr int i = strmatch("m0", "m0"); // OK
constexpr int j = extract(std::make_tuple(10, 20), "m0");
constexpr int k = extract(std::make_tuple(10, 20), "m1");
return 0;
}
Your code is ill-formed. The problem is that array is not a core constant expression, so can't be used in the template argument in the call to std::get:
template<unsigned N>
constexpr int extract(const std::tuple<int, int> & t1, const char (&array)[N]) {
return std::get<strmatch(array, "m0")>(t1);
}
Remember that constexpr functions can be called at runtime: this code would use the value of a runtime parameter to this function (array) during translation (in the evaluation of the call to strmatch).

Boost.Variant Vs Virtual Interface Performance

I'm trying to measure a performance difference between using Boost.Variant and using virtual interfaces. For example, suppose I want to increment different types of numbers uniformly, using Boost.Variant I would use a boost::variant over int and float and a static visitor which increments each one of them. Using class interfaces I would use a pure virtual class number and number_int and number_float classes which derive from it and implement an "increment" method.
From my testing, using interfaces is far faster than using Boost.Variant.
I ran the code at the bottom and received these results:
Virtual: 00:00:00.001028
Variant: 00:00:00.012081
Why do you suppose this difference is? I thought Boost.Variant would be a lot faster.
** Note: Usually Boost.Variant uses heap allocations to guarantee that the variant would always be non-empty. But I read on the Boost.Variant documentation that if boost::has_nothrow_copy is true then it doesn't use heap allocations which should make things significantly faster. For int and float boost::has_nothrow_copy is true.
Here is my code for measuring the two approaches against each other.
#include <iostream>
#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/format.hpp>
const int iterations_count = 100000;
// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
template <typename T>
void operator() (T& t) const {
t += N;
}
};
// a number interface
struct number {
virtual void increment() = 0;
};
// number interface implementation for all types
template <typename T>
struct number_ : number {
number_(T t = 0) : t(t) {}
virtual void increment() {
t += 1;
}
T t;
};
void use_virtual() {
number_<int> num_int;
number* num = &num_int;
for (int i = 0; i < iterations_count; i++) {
num->increment();
}
}
void use_variant() {
typedef boost::variant<int, float, double> number;
number num = 0;
for (int i = 0; i < iterations_count; i++) {
boost::apply_visitor(add<1>(), num);
}
}
int main() {
using namespace boost::posix_time;
ptime start, end;
time_duration d1, d2;
// virtual
start = microsec_clock::universal_time();
use_virtual();
end = microsec_clock::universal_time();
// store result
d1 = end - start;
// variant
start = microsec_clock::universal_time();
use_variant();
end = microsec_clock::universal_time();
// store result
d2 = end - start;
// output
std::cout <<
boost::format(
"Virtual: %1%\n"
"Variant: %2%\n"
) % d1 % d2;
}
For those interested, after I was a bit frustrated, I passed the option -O2 to the compiler and boost::variant was way faster than a virtual call.
Thanks
This is obvious that -O2 reduces the variant time, because that whole loop is optimized away. Change the implementation to return the accumulated result to the caller, so that the optimizer wouldn't remove the loop, and you'll get the real difference:
Output:
Virtual: 00:00:00.000120 = 10000000
Variant: 00:00:00.013483 = 10000000
#include <iostream>
#include <boost/variant/variant.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/format.hpp>
const int iterations_count = 100000000;
// a visitor that increments a variant by N
template <int N>
struct add : boost::static_visitor<> {
template <typename T>
void operator() (T& t) const {
t += N;
}
};
// a visitor that increments a variant by N
template <typename T, typename V>
T get(const V& v) {
struct getter : boost::static_visitor<T> {
T operator() (T t) const { return t; }
};
return boost::apply_visitor(getter(), v);
}
// a number interface
struct number {
virtual void increment() = 0;
};
// number interface implementation for all types
template <typename T>
struct number_ : number {
number_(T t = 0) : t(t) {}
virtual void increment() { t += 1; }
T t;
};
int use_virtual() {
number_<int> num_int;
number* num = &num_int;
for (int i = 0; i < iterations_count; i++) {
num->increment();
}
return num_int.t;
}
int use_variant() {
typedef boost::variant<int, float, double> number;
number num = 0;
for (int i = 0; i < iterations_count; i++) {
boost::apply_visitor(add<1>(), num);
}
return get<int>(num);
}
int main() {
using namespace boost::posix_time;
ptime start, end;
time_duration d1, d2;
// virtual
start = microsec_clock::universal_time();
int i1 = use_virtual();
end = microsec_clock::universal_time();
// store result
d1 = end - start;
// variant
start = microsec_clock::universal_time();
int i2 = use_variant();
end = microsec_clock::universal_time();
// store result
d2 = end - start;
// output
std::cout <<
boost::format(
"Virtual: %1% = %2%\n"
"Variant: %3% = %4%\n"
) % d1 % i1 % d2 % i2;
}

Resources