I'm using spline module in Eigen, and Assertion failed when I set the type of Spline<double, 1> as member variables.
this is a example,
#include "Eigen/eigen"
#include "unsupported/Eigen/splines"
using namespace Eigen;
class Spline1d
{
Spline<double, 1> spl1d;
public:
~Spline1d() {};
Spline1d() {};
Spline1d(const MatrixXd &input) {
spl1d = SplineFitting<Spline<double, 1> >::Interpolate(input.row(1), 1, input.row(0));
}
};
int main()
{
MatrixXd vals(2, 5);
vals << 1.0, 2.0, 3.0, 4.0, 5.0,
1.0, 2.0, 3.0, 4.0, 5.0;
// Spline1d spl(vals); // case 1
Spline<double, 1> spl1d = // case 2
SplineFitting<Spline<double, 1>>::Interpolate(vals.row(1), 1, vals.row(0));
return 0;
}
comment case 1 , using case 2, it works fine.
But comment case 2, using case 1, it fails, and it is run time error.
this is the Error message in command line,
Assertion failed: v == T(Value), file d:\onedrive\documents\codes\library\eigen\
src/Core/util/XprHelper.h, line 53
Case 2 is not an assignment, but a constructor.
Change your case 1 to
Spline1d(const MatrixXd &input)
: spl1d(SplineFitting<Spline<double, 1> >::Interpolate(input.row(1), 1, input.row(0))){
}
and it will build.
Related
I have this code that cannot be compiled by gcc 8, but I cannot understand why.
#include <iostream>
#include <algorithm>
#include <random>
using namespace std;
template<class... T>
void diagnose(T... x);
int main()
{
auto d = normal_distribution<double>(0.0, 1.0);
auto g = default_random_engine();
cout << d(g) << endl;
auto gen = [=](){
//diagnose(d, g);
return d(g); // ******
};
cout << gen() << endl;
}
The error message says (pointing to the line marked by *******):
error: no match for call to ‘(const std::normal_distribution<double>) (const std::linear_congruential_engine<long unsigned int, 16807, 0, 2147483647>&)
The code, however, works if I change the capture to be by reference.
If I uncomment the commented //diagnose line, the error message is like this (need also change return d(g) to return 1.0):
undefined reference to `void diagnose<std::normal_distribution<double>, std::linear_congruential_engine<unsigned long, 16807ul, 0ul, 2147483647ul> >(std::normal_distribution<double>, std::linear_congruential_engine<unsigned long, 16807ul, 0ul, 2147483647ul>)'
As you can see, in the capture-by-value case, the parameter g is a const reference. But the const does not appear in diagnosis.
Can somebody explain what is going on here?
You are passing d by value [=] so copy of this object is created inside lambda, but body of lambda function is const so you cannot change object inside lambda body. normal_distribution::operator() member is not-const. In const members you can invoke only const methods for member objects. You can resolve it by adding mutable to lambda
auto gen = [=]() mutable {
//diagnose(d, g);
return d(g); // ******
};
or passing d by reference
auto gen = [&](){
//diagnose(d, g);
return d(g); // ******
};
std::string (std::basic_string) have assignment operator for 'char' type.
But, for this reason, std::string may assign any integral types.
See little example.
#include <string>
enum MyEnum{ Va = 0, Vb = 2, Vc = 4 };
int main(){
std::string s;
s = 'a'; // (1) OK - logical.
s = Vc; // (2) Ops. Compiled without any warnings.
s = true; // (3) Ops....
s = 23; // (4) Ops...
}
Q: How disable (or add warning ) (2, 3, 4) situations ??
There is a related Question
Given the constraints of C++03 and GCC 4.8 as in the tags, I could not get -Wconversion to do anything useful (and in GCC 7 it doesn't even generate the warnings for me despite telling it that I'm using --std=c++03).
As such, there's a good practical solution that requires only minimal change at your calling site:
Proxy the assignment via a class object that wraps your string and that allows assignment from char but disallows it from int:
#include <string>
enum MyEnum{ Va = 0, Vb = 2, Vc = 4 };
struct string_wr {
string_wr (std::string& s) : val(s) {}
operator std::string& () const { return val; }
// we explicitly allow assigning chars.
string_wr& operator= (char) { return *this; }
// ww explicitly disable assigning ints by making the operator unreachable.
private:
string_wr& operator= (int);
private:
std::string& val;
};
int main(){
std::string s;
s = 'a'; // (1) OK - logical.
s = Vc; // (2) Ops. Compiled without any warnings.
s = true; // (3) Ops....
s = 23; // (4) Ops...
string_wr m(s); // this is the only real change at the calling site
m = 'a'; // (1) OK - logical.
m = Vc; // (2) Should fail with "assignment is private" kind of error.
m = true; // (3) Should fail...
m = 23; // (4) Should fail...
}
However, if your final goal is to specifically get warnings or errors when using std::string, your best option in C++03 is to patch the <string> header to add the private int-assignment operator shown in the class above. But that means patching a system header and the procedure and results will be dependant on your compiler version (and will have to be repeated in each installation and compiler version).
Microsoft Visual Studio Professional 2015 Version 14.0.25431.01 Update 3
does not issue errors when compiling the code below. Am I missing something?
Thank you.
#include <iostream>
template < class T > constexpr T oops( T s )
{
std::cout << s; // ignored - no code is generated
return s;
}
int main()
{
static_assert( oops( 1 ) == 1, "!" ); // non-constant condition not detected
return 0;
}
There is a question similar to this but it does not answer my question. I am working on a GUI using GTKMM. I am trying to pass a single char in the callback of my button.
This letter, is then assigned to the global variable letter. However, I don't understand pointers and have been trying to get this to work for quite a while without success.
main.cpp
#include <gtkmm.h>
#include "window.h"
int main(int argc, char *argv[])
{
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "com.gtkmm.tutorial3.base");
mywindow window;
return app->run(window);
}
window.cpp
#include "window.h"
mywindow::mywindow()
{
set_default_size(480, 320);
set_title("Transfer");
Gtk::Box *vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0));
add(*vbox);
Gtk::Grid *grid = Gtk::manage(new Gtk::Grid);
grid->set_border_width(10);
vbox->add(*grid);
Gtk::Button *a = Gtk::manage(new Gtk::Button("A"));
//a->set_hexpand(true);
//a->set_vexpand(true);//%%%%%%%% next line is the issue%%%%%%%%%
a->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_click('a')));
grid->attach(*a, 0, 0, 1, 1);//x=0,y=0, span 1 wide, and 1 tall
Gtk::Button *b = Gtk::manage(new Gtk::Button("B"));
//b->set_hexpand(true);
//b->set_vexpand(true);
b->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_click('b')));
grid->attach(*b, 1, 0, 1, 1);
Gtk::Button *c = Gtk::manage(new Gtk::Button("C"));
//c->set_hexpand(true);
//c->set_vexpand(true);
c->signal_clicked().connect(sigc::mem_fun(*this, &mywindow::on_click('c')));
grid->attach(*c, 2, 0, 1, 1);
vbox->show_all();
}
mywindow::~mywindow()
{
//dtor
}
void mywindow::on_click(char l)
{
letter = l;
}
window.h
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <gtkmm.h>
class mywindow : public Gtk::Window
{
public:
mywindow();
virtual ~mywindow();
protected:
char letter;//global variable where the letter is stored
char on_click(char l);
private:
};
#endif // MYWINDOW_H
I tried replacing the * pointer with & and vice-versa for this and mywindow but I haven't gotten it to work and have no idea how to proceed.
First of all there is gtkmm3 tutorial.
From there:
you can't hook a function with two arguments to a signal expecting none (unless you use an adapter, such as sigc::bind(), of course).
So you need something like this:
c->signal_clicked().connect(sigc::bind<char>(sigc::mem_fun(*this,&mywindow::on_click), "c"));
On a side note:
If you have problem with pointers you could try smart pointers but to be honest I think it would be better for you to understand them.
I have this test source:
#include <stdio.h>
int main()
{
int x;
printf("x=%d\n", _Generic('x', int: 1, default: 0));
return 0;
}
Compiling with c++ (from GCC 4.9.2) fails:
t.cpp: In function ‘int main()’:
t.cpp:7:33: error: expected primary-expression before ‘int’
printf("x=%d\n", _Generic('x', int: 1, default: 0));
^
t.cpp:7:41: error: expected primary-expression before ‘default’
printf("x=%d\n", _Generic('x', int: 1, default: 0));
^
t.cpp:7:51: error: ‘_Generic’ was not declared in this scope
printf("x=%d\n", _Generic('x', int: 1, default: 0));
The compiler arguments are:
c++ --std=c++11 t.cpp -o t
What am I doing wrong?
_Generic is a C11 feature. It is not present in C++ (any version at least up to C++14 - I don't really expect it to be added either).
If you want to use it, you'll need to write C code, and use a compiler that supports that standard (reasonably recent versions of gcc and clang do for example, using -std=c11).
If you want to write C++, use overloading or templates instead, for example:
#include <iostream>
int foo(int) { return 1; }
int foo(char) { return 0; }
int main()
{
std::cout << "x=" << foo('x') << std::endl;
}
This prints x=0 in C++, the foo(char) overload is the best match.
Note that there's difference between C and C++ that might trick you here too: 'x' is a char in C++. It's an int in C. So if _Generic had been implemented (maybe as an extension) by your compiler, chances are you'd get different output when compiling your example as C versus compiling as C++.
Here's the C++ form (forgive me for using the using directive, I know its bad form):
#include <iostream>
using namespace std;
template< typename T> T do_something(T argument) {
// Put here what you need
}
int main()
{
int x;
cout << "x" << (x = do_something(x));
return 0;
}
_Generic is C11, you're probably using a C++ compiler when you meant to use a C compiler.