I tried to implement the method of Horner and faced a problem:
root#host:~# cat | g++ -x c++ -std=gnu++11 - && ./a.out
#include <iostream>
#include <iomanip>
#include <iterator>
#include <vector>
#include <numeric>
#include <algorithm>
#include <random>
#include <chrono>
#include <cstdlib>
template< typename F >
class horner
{
public :
typedef std::vector< F > V;
horner(F const & x_, V const & c_)
: x(x_)
, c(c_)
, y(0.0L)
{ ; }
operator F const () const
{
return std::accumulate(c.rbegin(), c.rend(), *this).y;
}
private :
friend horner std::accumulate< typename V::const_reverse_iterator, horner >(typename V::const_reverse_iterator, typename V::const_reverse_iterator, horner);
void operator = (F const & rhs)
{
y = rhs;
}
operator F ()
{
y *= x;
return y;
}
F const & x;
V const & c;
F y;
};
#define N_COEFF_PARABOLA 3
int main()
{
typedef double F;
typedef typename horner< F >::V V;
V c;
unsigned seed(std::chrono::system_clock::now().time_since_epoch().count());
std::cout << "seed = 0x"
<< std::uppercase << std::hex << std::setfill('0') << std::setw(sizeof(seed) * 2)
<< seed << std::endl;
std::mt19937 generator(seed);
std::generate_n(std::back_inserter(c), N_COEFF_PARABOLA, generator);
std::cout << "coefficients: ";
std::copy(c.begin(), c.end(), std::ostream_iterator< F >(std::cout, " "));
std::cout << ';' << std::endl;
F const x(generator());
F const y(horner< F >(x, c));
std::cout << "y(" << x << ") = " << y << std::endl;
// naive
F xx(1.0L);
F yy(0.0L);
for (typename V::size_type i(0); i < c.size(); ++i) {
yy += c[i] * xx;
xx *= x;
}
std::cout << "y'(" << x << ") = " << yy << std::endl;
return EXIT_SUCCESS;
}
// press ^D
<stdin>: In function ‘int main()’:
<stdin>:39:5: error: ‘horner<F>::operator F() [with F = double]’ is private
<stdin>:71:32: error: within this context
root#host:~#
In my view the problem should not arise, since main() only sees operator F const & () const version of the type conversion operator. But it is.
What is the reason of the error?
The concepts of visibility and accessibility are completely orthogonal in C++. If a method is visible, but not accessible, the compiler may select it in overload resolution and produce a hard error because it can't use it. This is done on purpose so code does not change semantics silently when it gains or looses access.
Related
I'm new using the boost::multiprecision library and tried to use it combination with boost::math::interpolators::cardinal_cubic_b_spline however I can't compile the program.
The example code is
#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
#include <iostream>
#include <boost/multiprecision/gmp.hpp>
using boost::multiprecision::mpf_float_50;
int main() {
std::vector<mpf_float_50> v(10);
mpf_float_50 step(0.01);
for (size_t i = 0; i < v.size(); ++i) {
v.at(i) = sin(i*step);
}
mpf_float_50 leftPoint(0.0);
boost::math::interpolators::cardinal_cubic_b_spline<mpf_float_50> spline(v.begin(), v.end(), leftPoint, step);
mpf_float_50 x(3.1);
mpf_float_50 tmpVal = spline(x);
std::cout << tmpVal << std::endl;
return 0;
}
When change the type of variables to boost::multiprecision::cpp_bin_float_50 the program is working. Also, boost::multiprecision::mpf_float_50 is working in all other examples I have tried.
The error I get is:
/home/..../main.cpp:19:31: required from here
/usr/include/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp:50:10: error: conversion from ‘expression<boost::multiprecision::detail::function,boost::multiprecision::detail::abs_funct<boost::multiprecision::backends::gmp_float<50> >,boost::multiprecision::detail::expression<boost::multiprecision::detail::subtract_immediates, boost::multiprecision::number<boost::multiprecision::backends::gmp_float<50> >, long unsigned int, void, void>,[...],[...]>’ to non-scalar type ‘expression<boost::multiprecision::detail::subtract_immediates,boost::multiprecision::number<boost::multiprecision::backends::gmp_float<50> >,long unsigned int,[...],[...]>’ requested
The same error appeared for cpp_dec_float_50, mpfr_float_50 etc. I'm not sure what I'm doing wrong.
The selected type. is the GMP backend. To give it the usual operators, it is wrapped in the frontend template number<>:
Live On Coliru
using F = boost::multiprecision::mpf_float_50;
int main() {
F a = 3, b = 2;
F c = b - a;
std::cout << "a:" << a << ", b:" << b << ", c:" << c << std::endl;
b = abs(b - a);
std::cout << "a:" << a << ", b:" << b << ", c:" << c << std::endl;
}
Prints
a:3, b:2, c:-1
a:3, b:1, c:-1
However, the number<> enables expression templates by default. That means, typeof(F{} - F{}) is not necessarily F, but something like:
namespace mp = boost::multiprecision;
using F = mp::mpf_float_50;
int main() {
F a = 3, b = 2;
mp::detail::expression<mp::detail::subtract_immediates, F, F> //
c = b - a;
Template expressions can greatly optimize some code, e.g. by simplifying evaluation of complicated expressions.
However, some generic code doesn't deal well with the expression templates. Therefore you can turn them off:
namespace mp = boost::multiprecision;
using F = mp::number<mp::gmp_float<50>, mp::et_off>;
Now it all compiles, and probably works as it should.
Live On Coliru
#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
#include <iostream>
#include <boost/multiprecision/gmp.hpp>
namespace mp = boost::multiprecision;
using F = mp::number<mp::gmp_float<50>, mp::et_off>;
int main() {
std::vector<F> v(10);
F step(0.01);
for (size_t i = 0; i < v.size(); ++i) {
v.at(i) = sin(i * step);
}
F leftPoint(0.0);
boost::math::interpolators::cardinal_cubic_b_spline<F> spline(v.begin(), v.end(), leftPoint, step);
F x(3.1);
F tmpVal = spline(x);
std::cout << tmpVal << std::endl;
}
Now printing:
0.0449663
In one of my projects I'm using a small utility function, which takes a Message struct and a lambda function, that modifies this message struct.
Now, I unintentionally passed a lambda without the necessary reference &. It perfectly compiles, but doesn't gave the desired output.
As for me, there should be one of the two following behaviors:
Forgetting to write auto&, but just auto should lead to compilation errors
Writing just auto should be interpreted as auto&.
It is possible to prevent compilation in case of a missing & or even better to interpret auto as auto& automatically?
#include <iostream>
#include <functional>
#include <boost/variant.hpp>
struct Message {
int x;
int y;
};
void changeMessage(Message& m, const std::function<void(Message&)>& messageModifier) {
std::cout << "Message before:" << m.x << " " << m.y << "\n";
messageModifier(m);
std::cout << "Message after:" << m.x << " " << m.y << "\n";
}
int main(int, char**) {
{
std::function<void(int&)> f = [](int&) {};
std::function<void(int)> g = [](int) {};
f = g; // This compiles.
}
{
std::function<void(int&)> f = [](int&) {};
std::function<void(int)> g = [](int) {};
//g = f; // This does not compile. Makes perfect sense.
}
Message m{ 10,20 };
{
changeMessage(m, [](auto m) { m.x++; m.y--; }); // User unintentionally forgot &! Can I prevent this from compilation?
std::cout << "Message outside: " << m.x << " " << m.y << "\n";
}
{
changeMessage(m, [](auto& m) { m.x++; m.y--; });
std::cout << "Message outside: " << m.x << " " << m.y << "\n";
}
}
One way to prevent passing Message by value (and auto itself is never a reference) is to disable copy construction:
struct Message {
Message() = default;
Message(const Message&) = delete;
int x;
int y;
};
Another solution suggested by #L. F. is to check that lambda doesn't accept rvalues:
template<class Fn>
void change_message(Message& m, Fn fn) {
static_assert(!std::is_invocable_v<Fn, Message&&>);
fn(m);
}
I'm trying to understand why I can use an ostream_iterator for Edge1 but not for Edge in the following code:
#include <fstream>
#include <iostream> // for std::cout
#include <utility> // for std::pair
using VertexName = uint32_t;
using Edge = std::pair<VertexName, VertexName>;
struct Edge1 : public Edge {
Edge1(VertexName x, VertexName y) : Edge(x,y) {};
};
std::ostream&
operator<<(std::ostream& os, const Edge& e) {
os << "(" << e.first << ", " << e.second << ")";
return os;
}
int main(int,char*[])
{
auto e1 = Edge(4,5);
auto e2 = Edge1(5,6);
std::cout << e1 << ", " << e2 << std::endl;
auto it = std::ostream_iterator<Edge1>(std::cout, ", ");
//*it++ = e1;
*it++ = e2;
}
```
Although I can print out both e1 and e2 using the overloaded operator<<(std::stream& os, const Edge& e) function, I get the following error from clang-5.0 if I try to change the ostream_iterator to std::stream_iterator<Edge>(std::cout, ", ") and uncomment the *it++ = e1 line.
error: invalid operands to binary expression ('ostream_type' (aka 'basic_ostream<char, std::__1::char_traits<char> >') and 'const std::__1::pair<unsigned int, unsigned int>')
*__out_stream_ << __value_;
~~~~~~~~~~~~~~ ^ ~~~~~~~~
/main.cpp:25:11: note: in instantiation of member function 'std::__1::ostream_iterator<std::__1::pair<unsigned int, unsigned int>, char, std::__1::char_traits<char> >::operator=' requested here
*it++ = e1;
Edge is not a type it's a type alias of std::pair.
And of course ADL is not finding the overload of operator<< for Edge because it's defined in the wrong namespace... and you're not allowed to inject an overload in the std namespace.
The workaround is:
#include <fstream>
#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <iterator> // for std::ostream_iterator
using VertexName = uint32_t;
// Edge is now a type, in the global namespace...
struct Edge : std::pair<VertexName, VertexName> {
using std::pair<VertexName, VertexName>::pair;
};
struct Edge1 : public Edge {
Edge1(VertexName x, VertexName y) : Edge(x,y) {};
};
// ...and this operator<< is defined in the global namespace so
// ADL will now find it.
std::ostream&
operator<<(std::ostream& os, const Edge& e) {
os << "(" << e.first << ", " << e.second << ")";
return os;
}
int main(int,char*[])
{
auto e1 = Edge(4,5);
auto e2 = Edge1(5,6);
std::cout << e1 << ", " << e2 << std::endl;
auto it = std::ostream_iterator<Edge>(std::cout, ", ");
*it++ = e1;
*it++ = e2;
}
I have this code that works already:
// mem_fun example
#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>
#include <string>
#include <sstream>
#include <map>
using namespace std;
struct C
{
C(int i): y_(i) {};
int y_;
string op1(int x)
{
std::ostringstream oss;
oss << "operation 1: " << x+y_;
return oss.str();
}
string op2(string x)
{
std::ostringstream oss;
oss << "operation 2: " << x << "+" << y_;
return oss.str();
}
};
struct container: map<string, C>
{
// doesn't compile
// void safeOperation(string key, ??? bound_function_and_arg_object )
template< typename argType >
void safeOperation(string key, string (C::*mf)(argType a), argType a)
{
iterator it = find(key);
if (it != end())
{
C* pC = &(it->second);
cout << (pC->*mf)(a) << "\n";
}
else
{
cout << "key: " << key << " missing\n";
}
}
};
int main () {
container objects;
objects.insert(container::value_type("a1", C(1)));
objects.insert(container::value_type("b2", C(2)));
objects.insert(container::value_type("c3", C(3)));
objects.safeOperation("a1", &C::op1, 1);
objects.safeOperation("b2", &C::op1, 2);
objects.safeOperation("d4", &C::op1, 4);
objects.safeOperation("c3", &C::op2, string("3"));
return 0;
}
I'd like to change the template function on the map to use std::mem_fun and to bind the parameters together with the operation, rather than specify them as separate parameters to safeOperation.
In other words, I'd prefer to call safeOperation similar to this:
// wrong, but hopefully communicates what I'm trying to do:
objects.safeOperation(someKey, bind(&C::op1, 4));
The sample code is here: http://cpp.sh/74pgb
I'm probably missing something simple, but appreciate the help.
When you bind a member function, the first argument has to be an instance of the class whose member function it is. So what you want to do is generalize safeOperation to take any function that can be called on a C*:
template< typename F >
void safeOperation(string key, F func) {
iterator it = find(key);
if (it != end())
{
C* pC = &(it->second);
cout << func(pC) << "\n";
}
else
{
cout << "key: " << key << " missing\n";
}
}
And then generate your funcs by binding with the argument, but also leaving a placeholder:
using namespace std:;placeholders;
objects.safeOperation("a1", std::bind(&C::op1, _1, 1));
// ^^
// placeholder for pC
boost/std::bind create an object with an implementation-specific type. The only requirement is that the object is callable using operator().
To handle any functional objects you can change your function template in the following way:
template< typename F >
void safeOperation(string key, F f)
{
// ...
cout << f(pC) << "\n";
// ...
objects.safeOperation("someKey", bind(&C::op1, placeholders::_1, 4));
That should enable almost the syntax you require.
I'm attempting to use boost::static_visitor to implement actions on a boost::variant type that affect the state of some variable. My approach was to contain all of the state variables in my command visitor class, but it seems this is not possible.
Here is my code example:
#include <string>
#include <sstream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
struct TypeA
{
int varA;
int varB;
};
struct TypeB
{
std::string varA;
std::string varB;
};
typedef boost::variant<TypeA, TypeB> MyVariantType;
class MyCommandVisitor : public boost::static_visitor<>
{
public:
//These are just examples, the actions only need to be able to touch
// internal variables.
void operator()(TypeA & t) const
{
m_runningSum += t.varA;
m_outStream << "TYPEA ACTION: " << t.varB << std::endl;
}
void operator(TypeB & t) const
{
m_charCount += t.varA.size();
m_outStream << t.varB << " ACTION " << t.varA << std::endl;
}
std::string emitWork(std::vector<MyVariantType> listOfVariants)
{
m_outStream.clear();
m_runningSum = 0;
m_charCount = 0;
BOOST_FOREACH(MyVariantType & v, listOfVariants)
{
boost::apply_visitor(*this, v);
}
return m_outStream.str();
}
protected:
int m_runningSum;
int m_charCount;
std::stringstream outStream;
}; //End class MyCommandVisitor
int main(int argc, char **argv)
{
TypeA ta;
ta.varA = 1;
ta.varB = 2;
TypeB tb;
tb.varA = "String1";
tb.varB = "String2";
std::vector<MyVariantType> listOfWork;
listOfWork.push_back(ta);
listOfWork.push_back(tb);
MyCommandVisitor myCV;
std::string result = myCV.emitWork(listOfWork);
std::cout << "Result:\n" << result << std::endl << std::endl;
return 0;
}
I hope this snippet gets across the gist of what I'm trying to accomplish. It won't compile, however, giving the [paraphrased] error:
error: no operator "<<" matches these operands
operand types are: const std::stringstream << const char [N]
m_outStream << "TYPE A ACTION: " << t.varB << std::endl;
^
I'm assuming this error is due to the const modifier that must be placed on the end of the operator() function prototype which makes the compiler believe that member variables cannot be modified by the function.
My question is thus:
What is the proper way to accomplish the visitor pattern (using boost::variant) with variables that must maintain state between visits?
There were a couple of typos, but I made a few mods and it works now. Essentially your static_visitor class is mutating itself on each visit, so the operator() methods can't be const.
#include <string>
#include <sstream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
#include <iostream>
struct TypeA
{
int varA;
int varB;
};
struct TypeB
{
std::string varA;
std::string varB;
};
typedef boost::variant<TypeA, TypeB> MyVariantType;
class MyCommandVisitor : public boost::static_visitor<>
{
public:
//These are just examples, the actions only need to be able to touch
// internal variables.
void operator()(TypeA & t)
{
m_runningSum += t.varA;
m_outStream << "TYPEA ACTION: " << t.varB << std::endl;
}
void operator()(TypeB & t)
{
m_charCount += t.varA.size();
m_outStream << t.varB << " ACTION " << t.varA << std::endl;
}
std::string emitWork(std::vector<MyVariantType> listOfVariants)
{
m_outStream.clear();
m_runningSum = 0;
m_charCount = 0;
BOOST_FOREACH(MyVariantType & v, listOfVariants)
{
boost::apply_visitor(*this, v);
}
return m_outStream.str();
}
protected:
int m_runningSum;
int m_charCount;
std::stringstream m_outStream;
}; //End class MyCommandVisitor
int main(int argc, char **argv)
{
TypeA ta;
ta.varA = 1;
ta.varB = 2;
TypeB tb;
tb.varA = "String1";
tb.varB = "String2";
std::vector<MyVariantType> listOfWork;
listOfWork.push_back(ta);
listOfWork.push_back(tb);
MyCommandVisitor myCV;
std::string result = myCV.emitWork(listOfWork);
std::cout << "Result:\n" << result << std::endl << std::endl;
return 0;
}
running on http://www.compileonline.com/compile_cpp11_online.php gives:
Compiling the source code....
$g++ -std=c++11 main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
Executing the program....
$demo
Result:
TYPEA ACTION: 2
String2 ACTION String1
I'd personally favour making the functor const. Instead, I like to bind the functor arguments to references:
static std::string emitWork(std::vector<MyVariantType> const listOfVariants) {
int sum = 0, charCount = 0;
std::stringstream os;
BOOST_FOREACH(MyVariantType const& v, listOfVariants) {
boost::apply_visitor(
boost::bind(MyCommandVisitor(), _1, boost::ref(os), boost::ref(sum), boost::ref(charCount)),
v);
}
return os.str();
}
Note that
emitWork can now be static, reentrant etc.
the operator() can now be const
The rest of the visitor would look like this:
struct MyCommandVisitor : boost::static_visitor<> {
void operator()(TypeA const& t, std::stringstream& os, int& sum, int& /*charCount*/) const {
sum += t.varA;
os << "TYPEA ACTION: " << t.varB << std::endl;
}
void operator()(TypeB const& t, std::stringstream& os, int& /*sum*/, int& charCount) const {
charCount += t.varA.size();
os << t.varB << " ACTION " << t.varA << std::endl;
}
};
See it Live On Coliru