code:
#include<iostream>
using namespace std;
template<class T, int N> class point {
T coordinate[N];
public:
point(const point<T,N>&);
const double& operator[](int i) const {
return coordinate[i];
}
};
template<class T, int N> point<T,N>::point(const point<T,N>&p)
{
for(int i=0;i<N;i++)
coordinate[i]=p.coordinate[i];
};
int main() {
point<int,2> P2;
point<double,3> P3;
cout<<P2[0]<<P3[1];
return 0;
}
output:
prog.cpp: In function ‘int main()’:
prog.cpp:17: error: no matching function for call to ‘point<int, 2>::point()’
prog.cpp:11: note: candidates are: point<T, N>::point(const point<T, N>&) [with T =
int, int N = 2]
prog.cpp:18: error: no matching function for call to ‘point<double, 3>::point()’
prog.cpp:11: note: candidates are: point<T, N>::point(const point<T, N>&) [with T =
double, int N = 3]
prog.cpp: In member function ‘const double& point<T, N>::operator[](int) const [with
T = int, int N = 2]’:
prog.cpp:19: instantiated from here
prog.cpp:8: warning: returning reference to temporary
Please help me sort out the faults.
The compiler-generated default constructor is not being provided because you have created a constructor of your own. Therefore when you create P2 with no arguments to its constructor, you need to define a default constructor for it to compile.
When you declare a variable something like,
point<int,2> P2;
It uses default constructor; it can be used in 2 scenarios:
You haven't declared ANY
constructor in your class body. Thus
compiler will generate a default one
automatically and you can use it.
You declare/define a default
constructor explicitly (be it empty,
if you don't do anything)
Since here you don't do anything: just declare an empty default constructor:
template<class T, int N> class point {
//...
public:
point() {} // <-- default constructor
};
This will clear your errors.
Also there is an Important Warning:
prog.cpp:8: warning: returning reference to temporary
That is because of your operator [].
Change the line,
const double& operator[](int i) const
To,
const T& operator[](int i) const // for <int, N> you should return 'int' not 'double'
The problem is that with these two lines
point<int,2> P2;
point<double,3> P3;
you are attempting to create two 'point' object via the default parameterless constructor.
However, this constructor is not automatically generated unless you do not specify any others. Implementing the default constructor will solve you problem
Related
I am unable to write a correct user defined conversion for a type Item. This is what I've tried:
#include <iostream>
#include <boost/optional.hpp>
struct A
{
int x;
};
struct Item
{
boost::optional<int> x_;
Item(){}
Item(const A& s)
: x_(s.x)
{
}
operator boost::optional<A>() const {
boost::optional<A> s;
if (x_) {
s->x = *x_;
}
return s;
}
};
std::vector<A> getA(const std::vector<Item> &items) {
std::vector<A> a;
for (const auto &i : items) {
if (i.x_) {
a.push_back(*static_cast<boost::optional<A>>(i)); // <- this line causes error
}
}
return a;
}
That is how I use it:
int main() {
A a;
a.x = 3;
Item i(a);
auto v = getA({i});
return 0;
}
g++ -std=c++11 says:
In file included from /usr/include/boost/optional.hpp:15:0,
from test.cpp:2:
/usr/include/boost/optional/optional.hpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::construct(const Expr&, const void*) [with Expr = Item; T = A]’:
/usr/include/boost/optional/optional.hpp:262:25: required from ‘boost::optional_detail::optional_base<T>::optional_base(const Expr&, const Expr*) [with Expr = Item; T = A]’
/usr/include/boost/optional/optional.hpp:559:78: required from ‘boost::optional<T>::optional(const Expr&) [with Expr = Item; T = A]’
test.cpp:30:55: required from here
/usr/include/boost/optional/optional.hpp:392:8: error: no matching function for call to ‘A::A(const Item&)’
new (m_storage.address()) internal_type(expr) ;
^
/usr/include/boost/optional/optional.hpp:392:8: note: candidates are:
test.cpp:3:8: note: A::A()
struct A
^
test.cpp:3:8: note: candidate expects 0 arguments, 1 provided
test.cpp:3:8: note: constexpr A::A(const A&)
test.cpp:3:8: note: no known conversion for argument 1 from ‘const Item’ to ‘const A&’
test.cpp:3:8: note: constexpr A::A(A&&)
test.cpp:3:8: note: no known conversion for argument 1 from ‘const Item’ to ‘A&&’
Why does it try to find A struct constructor instead of use user defined conversion operator?
You may point me directly to any position of the user-defined conversion page because I am unable to find any reason for this. For example,
User-defined conversion function is invoked on the second stage of the implicit conversion, which consists of zero or one converting constructor or zero or one user-defined conversion function.
in my opinion directly says that if no conversion constructor is defined then user-defined conversion function will be used. Am I wrong? And if yes, how can I implement user-defined conversion then without defining conversion cunstructor in struct A ?
You have two issues with your code. Your optional operator never initializes the boost::optional. If you don't do that, accessing members is undefined behavior. What you have to do is:
operator boost::optional<A>() const {
boost::optional<A> s;
if (x_) {
s = A{*x_};
}
return s;
}
The second issue is when you do:
static_cast<boost::optional<A>>(i);
That is equivalent to:
boost::optional<A> __tmp(i);
But it turns out that boost::optional has an explicit template constructor. That will be preferred to your conversion function. The error you're seeing is the compiling going down the path of this factory constructor, where Item is not such a factory.
You could simply use boost::optional<A> directly:
std::vector<A> getA(const std::vector<Item> &items) {
std::vector<A> a;
for (boost::optional<A> opt : items) {
if (opt) {
a.push_back(*opt);
}
}
return a;
}
Or, since the constructor template is explicit, you could use the conversion operator in a non-explicit context:
boost::optional<A> opt = i;
a.push_back(*opt);
This has the added benefit of also being easier to read.
I am puzzled by the following piece of code:
#include <Eigen/Dense>
#include <vector>
class Foo {};
void f(Eigen::MatrixXd const &) {}
void f(std::vector<Eigen::MatrixXd> const &) {}
void g(Foo const &) {}
void g(std::vector<Foo> const &) {}
int main()
{
Foo a, b, c;
Eigen::MatrixXd x, y, z;
// f({x, y}); ambiguity, why?!
f({x, y, z}); // ok
g({a,b}); // ok
g({a,b,c}); // ok
}
If I un-comment the 3-rd code line in main(), I get an ambiguous call error,
/Users/vlad/so.cpp: In function 'int main()':
/Users/vlad/so.cpp:17:13: error: call of overloaded 'f(<brace-enclosed initializer list>)' is ambiguous
f({x, y}); //ambiguity, why?!
^
/Users/vlad/so.cpp:17:13: note: candidates are:
/Users/vlad/so.cpp:6:6: note: void f(const MatrixXd&)
void f(Eigen::MatrixXd const &) {}
^
/Users/vlad/so.cpp:7:6: note: void f(const std::vector<Eigen::Matrix<double, -1, -1> >&)
void f(std::vector<Eigen::MatrixXd> const &) {}
Calling it with 3 items in the init list works.
However, if instead of using Eigen matrices, I use my own class Foo (see the function g), everything works fine. I have absolutely no clue why the commented line is ambiguous when using Eigen. Any ideas?
PS: If I overload f so that it takes a std::initializer_list<Eigen::MatrixXd>, then the problem disappears, no more ambiguous call.
The error is most likely being caused by this constructor template.
template<typename T0, typename T1>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y)
{ ... }
Both that constructor and vector's initializer_list constructor are equally good matches in the function call f({x, y});, leading to the ambiguity error.
Here's a made up example with similar constructors and function calls that leads to an ambiguity error as well.
The code below is a minimal example of my problem. I created a simple template class containing a fixed-size array, and overloaded the assignment operator to accept any class defining the methods size() and begin() (eg, initializer_lists). I don't understand why g++ is not able to resolve my call to this operator (I'm using gcc 4.6):
***.cpp: In function ‘int main()’:
***.cpp:46:22: error: no match for ‘operator=’ in ‘a = {42, -1.0e+0, 3.14158999999999988261834005243144929409027099609375e+0}’
***.cpp:46:22: note: candidates are:
***.cpp:23:8: note: template<class U> A<T, N>::self& A::operator=(const U&) [with U = U, T = double, unsigned int N = 3u, A<T, N>::self = A<double, 3u>]
***.cpp:8:7: note: A<double, 3u>& A<double, 3u>::operator=(const A<double, 3u>&)
***.cpp:8:7: note: no known conversion for argument 1 from ‘<brace-enclosed initialiser list>’ to ‘const A<double, 3u>&’
***.cpp:8:7: note: A<double, 3u>& A<double, 3u>::operator=(A<double, 3u>&&)
***.cpp:8:7: note: no known conversion for argument 1 from ‘<brace-enclosed initialiser list>’ to ‘A<double, 3u>&&’
The first candidate is listed correctly, but there is no error message associated. Here is the code:
#include <iostream>
#include <algorithm>
#include <initializer_list>
// ------------------------------------------------------------------------
template <typename T, unsigned N>
class A
{
public:
typedef A<T,N> self;
// Default ctor
A() {}
// Copy ctor
template <typename U>
A( const U& other ) { operator=(other); }
// Assignemnt
template <typename U>
self& operator= ( const U& other )
{
if ( other.size() == N )
std::copy_n( other.begin(), N, m_data );
return *this;
}
// Display contents
void print() const
{
for ( unsigned i = 0; i < N; ++i )
std::cout << m_data[i] << " ";
std::cout << std::endl;
}
private:
T m_data[N];
};
// ------------------------------------------------------------------------
int main()
{
A<double,3> a;
a = {42,-1.0,3.14159};
a.print();
}
Does anyone know why this might be ambiguous, or what I did wrong?
Note: Ideally, I would even like to replace the first two lines of my main by a single one A<double,3> a = {42,-1.0,3.14159}; but I'm not sure how, I currently get the following error:
***: In function ‘int main()’:
***:45:34: error: could not convert ‘{42, -1.0e+0, 3.14158999999999988261834005243144929409027099609375e+0}’ from ‘<brace-enclosed initialiser list>’ to ‘A<double, 3u>’
Unlike auto, where a braced-init-list is deduced as an initializer_list, template argument deduction considers it to be a non-deduced context, unless there exists a corresponding parameter of type initializer_list<T>, in which case the T can be deduced.
From §14.8.2.1/1 [temp.deduct.call] (emphasis added)
Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers from P gives std::initializer_list<P0> for some P0 and the argument is an initializer
list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P0 as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5).
Thus the argument to your operator= is not deduced to be an initializer_list<double>. For the code to work, you must define an operator= that takes an initializer_list argument.
template <typename U>
self& operator= ( const std::initializer_list<T>& other )
{
if ( other.size() == N )
std::copy_n( other.begin(), N, m_data );
return *this;
}
A brace-enclosed initializer list does not necessarily have the type std::initializer_list<T>, so you need to specify that the assignment operator template expects an std::initializer_list:
template <typename U>
A& operator=(std::initializer_list<U> other )
{
if ( other.size() == N )
std::copy_n( other.begin(), N, m_data );
return *this;
}
or
A& operator=(std::initializer_list<double> other )
{
if ( other.size() == N )
std::copy_n( other.begin(), N, m_data );
return *this;
}
I must say, an assignment operator that silently fails if the sizes don't match doesn't seem like a great idea.
I'd say it's this:
A<double,3> a;
a = {42,-1.0,3.14159};
You are initializing a with default constructor, and then trying to use initializer list on already initialized object - which complains about lacking of appropriate operator= overload. Instead try:
A<double,3> a = {42,-1.0,3.14159};
EDIT:
You also didn't defined required constructor:
template <typename T, unsigned N>
class A
{
public:
A(std::initializer_list list) : m_data(list) {}
//...
}
There is polynomial class in Boost math library: Boost polynomial class. I want to expand abilities of this class by adding new functions and I use inheritance as follows:
#ifndef POLY_HPP
#define POLY_HPP
#include <boost/math/tools/polynomial.hpp>
template <class T>
class Poly : public boost::math::tools::polynomial<T>{
public:
Poly(const T* data, unsigned order) : boost::math::tools::polynomial<T>(data, order){
}
};
#endif
Now I declare two objects of this class and I want to add them:
int a[3] = {2, 1, 3};
Poly<int> poly(a, 2);
int b[2] = {3, 1};
Poly<int> poly2(b, 1);
std::cout << (poly + poly2) << std::endl;
But there is an error during compliation:
main.cpp: In function ‘int main()’:
main.cpp:28:26: error: ambiguous overload for ‘operator+’ in ‘poly + poly2’
/usr/local/include/boost/math/tools/polynomial.hpp:280:22: note: candidates are: boost::math::tools::polynomial<T> boost::math::tools::operator+(const U&, const boost::math::tools::polynomial<T>&) [with U = Poly<int>, T = int]
/usr/local/include/boost/math/tools/polynomial.hpp:256:22: note: boost::math::tools::polynomial<T> boost::math::tools::operator+(const boost::math::tools::polynomial<T>&, const U&) [with T = int, U = Poly<int>]
/usr/local/include/boost/math/tools/polynomial.hpp:232:22: note: boost::math::tools::polynomial<T> boost::math::tools::operator+(const boost::math::tools::polynomial<T>&, const boost::math::tools::polynomial<T>&) [with T = int]
make[2]: Leaving
There are defined three overloaded functions for operator+. I thought it should take:
boost::math::tools::polynomial<T> boost::math::tools::operator+(const boost::math::tools::polynomial<T>&, const boost::math::tools::polynomial<T>&)
because Poly class is inherited from Boost polynomial and arguments pass the best, however it doesn't happen. How to add two Poly class objects without explicit new definition of operator+?
This is not possible as far as I know, you'll need something like
template <class T>
Poly<T> operator + (const Poly<T>& a, const Poly<T>& b) {
return Poly<T>(static_cast< boost::math::tools::polynomial<T> >(a) +
static_cast< boost::math::tools::polynomial<T> >(b));
}
to disambiguate the call (which needs an appropriate conversion constructor from boost::math::tools::polynomial<T> to Poly<T> in your class...)
I want to use a stack to store indices of an array,so I use the following typedef,where istack is a template class for stack:
typedef istack<size_t> IndexStack;
and I declare a stack by
IndexStack stack;
But when I call the following function (where A.size() returns a size_t);
stack.push_back(A.size());
GCC gives the following error
sort.cpp: In function 'void quicksort2(Array&)':
sort.cpp:50:27: error: no matching function for call to 'istack<unsigned int>::push_back(size_t)'
iarray.h:103:8: note: candidate is: void istack<T>::push_back(T&) [with T = unsigned int]
How can I make it work?
#include <cstddef>
template <class T>
struct istack
{
void push_back(T& value);
std::size_t size() const;
};
int main()
{
typedef istack<size_t> IndexStack;
IndexStack a, stack;
stack.push_back(a.size());
}
This code produces an error
In function 'int main()':
13 no matching function for call to 'istack<unsigned int>::push_back(size_t)'
note 5 candidates are: void istack<T>::push_back(T&) [with T = unsigned int]
Note that it lists candidates. (I suspect you are not reading / posting the entire error message.)
The given candidate doesn't match the call, because the reference is non-const. A temporary (such as the result of a.size()) cannot be bound to a non-const reference.
push_back should be taking a const T& value