I'm trying to adapt an example from Stroustrup C++ 4th Ed Page 1182, to call a function from operator()() vs the bind. Unfortunately, I'm getting a number of compilation errors. The code that worked before is // commented out. Does anyone know how to resolve the errors?
#include <iostream>
#include <random>
#include <map>
#include <functional>
using namespace std;
class rand_int {
public:
rand_int(int lo, int hi) : p{lo,hi}, re{rd()} {}
// int operator()() const { return r(); }
int operator()() const { return
uniform_int_distribution<>{p}(re); }
private:
uniform_int_distribution<>::param_type p;
random_device rd;
default_random_engine re;
// function<int()> r = bind(uniform_int_distribution<>{p}, re);
};
int main()
{
map<int,int> m;
rand_int ri{0,9};
for (int i=0; i < 100; ++i) {
m[ri()]++;
}
for (map<int,int>::iterator it = m.begin();
it != m.end(); ++it)
cout << it->first << ", " << it->second << '\n';
return 0;
}
Compilation:
clang++ -Wall -std=c++11 -pedantic test252.cc && ./a.out
In file included from test252.cc:2:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/random:49:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:35:
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/uniform_int_dist.h:243:25: error:
no matching function for call to object of type 'const
std::linear_congruential_engine<unsigned long, 16807, 0, 2147483647>'
__ret = __uctype(__urng()) - __urngmin;
^~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/uniform_int_dist.h:166:24: note:
in instantiation of function template specialization
'std::uniform_int_distribution<int>::operator()<const
std::linear_congruential_engine<unsigned long, 16807, 0, 2147483647> >'
requested here
{ return this->operator()(__urng, _M_param); }
^
test252.cc:12:35: note: in instantiation of function template specialization
'std::uniform_int_distribution<int>::operator()<const
std::linear_congruential_engine<unsigned long, 16807, 0, 2147483647> >'
requested here
uniform_int_distribution<>{p}(re); }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:323:7: note:
candidate function not viable: 'this' argument has type 'const
std::linear_congruential_engine<unsigned long, 16807, 0, 2147483647>', but
method is not marked const
operator()()
^
This line:
uniform_int_distribution<>{p}(re);
modifies the member re. So the operator() can't be marked const.
You need to do:
int operator()() { // non-const method
return uniform_int_distribution<>{p}(re);
}
Here's a demo.
Related
The following code:
#include <vector>
#include <algorithm>
#include <thread>
#include <future>
#include <iostream>
int main() {
std::vector<int> v(1000);
for(unsigned i = 0; i < v.size(); i++) {
v[i] = i;
}
int bb = 2;
std::cout << v.back() << std::endl;
auto f = [&](int& x) {x = 2*x; bb=4; };
std::async(std::launch::async, std::for_each<decltype(v.begin()),decltype(f)>,
v.begin(), v.end(), f);
std::cout << v.back() << std::endl;
std::cout << "bb: " << bb;
return 0;
}
fails to compile with msvc version < 19.32.
e.g. the errors look like this with msvc = 19.29 (compiled on godbolt.org):
example.cpp
<source>(16): warning C4834: discarding return value of function with 'nodiscard' attribute
C:/data/msvc/14.31.31108/include\future(314): error C2280: 'main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37> &main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>::operator =(const main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37> &)': attempting to reference a deleted function
<source>(14): note: see declaration of 'main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>::operator ='
<source>(14): note: 'main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37> &main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>::operator =(const main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37> &)': function was explicitly deleted
C:/data/msvc/14.31.31108/include\future(309): note: while compiling class template member function 'void std::_Associated_state<_Ty>::_Set_value_raw(_Ty &&,std::unique_lock<std::mutex> *,bool)'
with
[
_Ty=main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>
]
C:/data/msvc/14.31.31108/include\future(305): note: see reference to function template instantiation 'void std::_Associated_state<_Ty>::_Set_value_raw(_Ty &&,std::unique_lock<std::mutex> *,bool)' being compiled
with
[
_Ty=main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>
]
C:/data/msvc/14.31.31108/include\future(722): note: see reference to class template instantiation 'std::_Associated_state<_Ty>' being compiled
with
[
_Ty=main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>
]
C:/data/msvc/14.31.31108/include\future(720): note: while compiling class template member function 'std::_State_manager<_Ty>::~_State_manager(void) noexcept'
with
[
_Ty=main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>
]
C:/data/msvc/14.31.31108/include\future(879): note: see reference to function template instantiation 'std::_State_manager<_Ty>::~_State_manager(void) noexcept' being compiled
with
[
_Ty=main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>
]
C:/data/msvc/14.31.31108/include\future(860): note: see reference to class template instantiation 'std::_State_manager<_Ty>' being compiled
with
[
_Ty=main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>
]
<source>(17): note: see reference to class template instantiation 'std::future<main::<lambda_fa7e30e7ff267c277ebbd82c8a7f9e37>>' being compiled
https://godbolt.org/z/WsovKcnnc
It is successfully compiled with gcc, icc, clang and msvc (>=19.32) (using -lpthread).
Is it possible to make it compile with msvc version = 19.29 (VS19) ?
I tried the option /std:c++latest but it did not make a difference.
If Marek R is right about the problem being MSVC's STL implementation, you may be able to avoid calling std::async by using std::packaged_task and std::thread instead.
#include <thread>
#include <future>
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>
int main()
{
std::vector<int> v(100);
std::iota(v.begin(), v.end(), 0);
int bb = -2;
auto f = [&] (int& x) {
x = 2 * x;
bb = 4;
};
using Iter = decltype(v.begin());
using Fun = decltype(f);
auto foreach = [] (Iter begin, Iter end, Fun f) {
std::for_each<Iter, Fun>(begin, end, f);
};
std::packaged_task<void(Iter, Iter, Fun)> task(foreach);
auto future = task.get_future();
std::thread t(std::move(task), v.begin(), v.end(), f);
future.get();
t.join();
//
std::cout << v.back() std::endl;
std::cout << "bb: " << bb << std::endl;
return 0;
}
I would like to create a C++ script that uses map to execute heterogeneous functions, and stores the input/output in a map.
To deal with the heterogeneity I though to use the any type.
However, this creates problems, since the function pointer is not able to convert other type in any type.
Here is a minimal example that is not working, but illustrates what I would like to do:
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <map>
#include <any>
using namespace std;
string funct1(int a, int b)
{
int c= a+b;
string name = to_string(c);
return name ;
}
float funct2(int a, int b)
{
// float b2
float c=a-b;
return c ;
}
int main(void)
{
cout << "START" << endl;
std::map<std::string, std::any> ListObjIn; //
std::map<std::string, std::any> ListObjOut; //
typedef std::any (*FnPtr)(std::any, int);
std::map<std::string, FnPtr> ListCommand; //
//
ListObjIn["a1"] = 1;
ListObjIn["a2"] = 1.5;
ListCommand["do1"]= funct1;
ListCommand["do2"]= funct2;
// ListObjOut["res1"]= ListCommand["do1"]( std::any_cast<int>(ListObjIn["a1"]), 2);
ListObjOut["res1"]= ListCommand["do1"]( ListObjIn["a1"], 2);
cout << "RESULT 1=" << std::any_cast<string>(ListObjOut["res1"]) << endl;
ListObjOut["res2"]= ListCommand["do2"]( ListObjIn["a2"], 2);
cout << "RESULT 2=" << std::any_cast<string>(ListObjOut["res2"]) << endl;
cout << "END" << endl;
return(0);
}
I get the following error:
g++ -std=c++17 ./test.cpp
./test.cpp: In function ‘int main()’:
./test.cpp:34:24: error: invalid conversion from ‘std::__cxx11::string (*)(int, int) {aka std::__cxx11::basic_string<char> (*)(int, int)}’ to ‘std::map<std::__cxx11::basic_string<char>, std::any (*)(std::any, int)>::mapped_type {aka std::any (*)(std::any, int)}’ [-fpermissive]
ListCommand["do1"]= funct1;
^~~~~~
./test.cpp:35:24: error: invalid conversion from ‘float (*)(int, int)’ to ‘std::map<std::__cxx11::basic_string<char>, std::any (*)(std::any, int)>::mapped_type {aka std::any (*)(std::any, int)}’ [-fpermissive]
ListCommand["do2"]= funct2;
^~~~~~
I tried to change the input and output type of the function (ie string and float) to any, but this creates problems of conversion at other places.
So it is possible to have something very close to my original example, keeping the heterogeneity of type in/out and map of functions ? Or should think to workaround ? if so, which one ?
You should probably generify return type with std::any:
https://godbolt.org/z/G1EhqY
Why am I getting this error? I'm just making a class object. What am I missing?
Is it because of the empty body methods and constructor? I'm not sure here.
The tutorial im using is from here:
https://www.youtube.com/watch?v=KkwX7FkLfug
Code:
#include <vector>
#include <iostream>
class Neuron {};
typedef std::vector<Neuron> Layer;
class Net
{
public:
Net(const std::vector<unsigned> &topology) {};
void feedForward(const std::vector<double> &inputVals) {};
void backProp(const std::vector<double> &targetVals) {};
void getResults(std::vector<double> &resultVals) const {};
private:
// [layerNum][neuronNum]
std::vector<Layer> m_layers;
};
void Net::Net(const std::vector<unsigned> &topology)
{
unsigned numLayers = topology.size();
for (unsigned layerNum = 0; layerNum < numLayers; ++layerNum){
m_layers.push_back(Layer());
for (unsigned neuronNum = 0; neuronNum <= topology[layerNum]; ++neuronNum){
m_layers.back().push_back(Neuron());
std::cout << "Made a neuron!" << std::endl;
}
}
}
int main(int argc, char *argv[])
{
std::vector<unsigned> topology;
topology.push_back(3);
topology.push_back(2);
topology.push_back(1);
Net myNet(topology);
std::vector<double> inputVals;
myNet.feedForward(inputVals);
std::vector<double> targetVals;
myNet.backProp(targetVals);
std::vector<double> resultVals;
myNet.getResults(resultVals);
return 0;
}
Running:
g++ e:/something/ProgrammingExt/0a_Testing/cpp/neural_network/neural-net-tutorial.cpp
Getting this error:
ERROR (0.39 seconds): e:/something/ProgrammingExt/0a_Testing/cpp/neural_network/neural-net-
tutorial.cpp:20:52: error: return type specification for constructor invalid
void Net::Net(const std::vector<unsigned> &topology)
^
e:/something/ProgrammingExt/0a_Testing/cpp/neural_network/neural-net-tutorial.cpp:20:6: error: redefinition of ’Net::Net(const std::vector<unsigned int>&)’
void Net::Net(const std::vector<unsigned> &topology)
^~~
e:/something/0a_Testing/cpp/neural_network/neural-net-tutorial.cpp:11:3: note: ’Net::Net(const std::vector<unsigned int>&)’ previously defined here
Net(const std::vector<unsigned> &topology) {};
^~~
The error messages tell you why you are getting them.
ERROR (0.39 seconds): [path]/neural-net-tutorial.cpp:20:52: error: return type specification for constructor invalid
void Net::Net(const std::vector<unsigned> &topology)
^
This is the first error. Constructors return nothing, not even void. So drop the void keyword from the indicated line.
[path]/neural-net-tutorial.cpp:20:6: error: redefinition of ’Net::Net(const std::vector<unsigned int>&)’
void Net::Net(const std::vector<unsigned> &topology)
^~~
[path]/neural-net-tutorial.cpp:11:3: note: ’Net::Net(const std::vector<unsigned int>&)’ previously defined here
Net(const std::vector<unsigned> &topology) {};
^~~
This is the second error. You have two definitions of the constructor for Net that takes a const std::vector<unsigned> & parameter. The duplicate is on line 20, the same line that triggered the earlier error about void. The original is on line 11, where you defined the constructor to have an empty body. There is an extraneous semicolon after this definition, which suggests there might have been an intent to convert the definition to a declaration at some point. That point is now. (The 6 and 3 in the error messages are positions within the indicated line. Your compiler decided to mark the errors at the start of the constructor's name.)
Since you apparently do not want this constructor to have an empty body, change the definition on line 11 from
Net(const std::vector<unsigned> &topology) {};
to a declaration by dropping the function body:
Net(const std::vector<unsigned> &topology);
C++ overloading can't be based on return type. So there are two functions with exact same argument and they are treated as the same function:
Net(const std::vector<unsigned> &topology) {};
and
void Net::Net(const std::vector<unsigned> &topology)
{
unsigned numLayers = topology.size();
for (unsigned layerNum = 0; layerNum < numLayers; ++layerNum){
m_layers.push_back(Layer());
for (unsigned neuronNum = 0; neuronNum <= topology[layerNum]; ++neuronNum){
m_layers.back().push_back(Neuron());
std::cout << "Made a neuron!" << std::endl;
}
}
}
That's why you got redefinition error.
Another problem is that constructor doesn't have a return type, but you give it a "void" for the second definition. That's why you got the first error:
tutorial.cpp:20:52: error: return type specification for constructor invalid
void Net::Net(const std::vector &topology)
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.
I tried to implement Properties in c++. I don't no why but if I want to compile my code there are quite a lot of errors. The main Idea was, that a template class and the tamplate constructor will give the requirement Informations.
I would be grateful if somebody could help me!
Compiling Message:
pi#raspberrypi ~/dev/property $ gcc -std=c++0x -o PropertyTest2 PropertyTest2.cpp
PropertyTest2.cpp:22:16: error: expected ‘;’ at end of member declaration
PropertyTest2.cpp:22:19: error: expected unqualified-id before ‘<’ token
PropertyTest2.cpp: In function ‘int main()’:
PropertyTest2.cpp:34:20: error: use of deleted function ‘PropertyTestClass::PropertyTestClass()’
PropertyTest2.cpp:8:7: error: ‘PropertyTestClass::PropertyTestClass()’ is implicitly deleted because the default definition would be ill-formed:
PropertyTest2.cpp:8:7: error: no matching function for call to ‘Property<int>::Property()’
PropertyTest2.cpp:8:7: note: candidates are:
Property4.cpp:21:2: note: template<int (** G)(), void (** S)(int&)> Property::Property()
Property4.cpp:6:7: note: constexpr Property<int>::Property(const Property<int>&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
Property4.cpp:6:7: note: constexpr Property<int>::Property(Property<int>&&)
Property4.cpp:6:7: note: candidate expects 1 argument, 0 provided
PropertyTest2.cpp:38:20: error: no matching function for call to ‘Property<int>::Set(int)’
PropertyTest2.cpp:38:20: note: candidate is:
Property4.cpp:30:7: note: void Property<T>::Set(T&) [with T = int]
Property4.cpp:30:7: note: no known conversion for argument 1 from ‘int’ to ‘int&’
Property Class (Property.cpp)
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
template <class T>
class Property {
private:
typedef T (*TGetter)(void);
typedef void (*TSetter)(T &);
TGetter Getter;
TSetter Setter;
public:
typedef T type;
template<TGetter *G,
TSetter *S
>
Property() {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(T &value) {
(this->Setter)(value);
}
};
#endif
Testing file (PropertyTest.cpp):
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter(void) {
return this->_age;
}
void AgeSetter(int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age<&PropertyTestClass::AgeGetter, &PropertyTestClass::AgeSetter>;
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Ok, this time fixed all the problems in your code.
Property.cpp:
#ifndef __PROPERTY_FH__
#define __PROPERTY_FH__
#include <boost/function.hpp>
template <class T>
class Property {
private:
typedef boost::function <T()> TGetter;
typedef boost::function <void(const T&)> TSetter;
TGetter Getter;
TSetter Setter;
public:
typedef T type;
Property(TGetter G, TSetter S) {
this->Getter = G;
this->Setter = S;
}
T Get(void) {
return (this->Getter)();
}
void Set(const T &value) {
(this->Setter)(value);
}
};
#endif
PropertyTests.cpp:
#ifndef __PROPERTY_TEST_FH__
#define __PROPERTY_TEST_FH__
#include <iostream>
#include <boost/bind.hpp>
#include "Property.cpp"
class PropertyTestClass {
private:
// ReadWrite Property for age
int _age;
int AgeGetter() {
return this->_age;
}
void AgeSetter(const int &value) {
this->_age = value;
}
public:
// ReadWrite Property for age
Property<int> age;
PropertyTestClass() : age(
boost::bind(&PropertyTestClass::AgeGetter, this),
boost::bind(&PropertyTestClass::AgeSetter, this, _1))
{}
};
#endif
/**
* Program Entry
**/
int main() {
std::cout << "Property Test Programm\n\n";
PropertyTestClass propTest;
std::cout << "ReadWrite Property for age\n";
propTest.age.Set(5);
std::cout << propTest.age.Get() << "\n";
return 0;
}
Output:
$ ./a.out
Property Test Programm
ReadWrite Property for age
5