I found the following class definition in the boost library 1.71.0 which is installed at /usr/include/boost in my case.
class BOOST_SYMBOL_VISIBLE seconds : public time_duration
{
public:
template <typename T>
explicit seconds(T const& s,
typename boost::enable_if<boost::is_integral<T>, void>::type* = BOOST_DATE_TIME_NULLPTR) :
time_duration(0,0, numeric_cast<sec_type>(s))
{}
};
The Above class definition can be found out at /usr/include/boost/date_time/posix_time/posix_time_duration.hpp
I am using following code-snippet where the class boost::posix_time::seconds is instantiated:
#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/format.hpp>
#include <boost/bind.hpp>
#include <boost/serialization/access.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/shared_array.hpp>
#include <boost/algorithm/string.hpp>
#include <chrono>
#include <vector>
#include <boost/date_time/posix_time/posix_time_duration.hpp>
int main()
{
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket socket(io_service);
boost::asio::deadline_timer timer(io_service);
timer.expires_from_now(boost::posix_time::seconds(60.0))
return 0;
}
Let's say I save the above code-snippet with the file name boost.cpp. Then I compile boost.cpp using the command
g++ -I /usr/include/boost -pthread boost.cpp
However, I am getting the following error:
boost.cpp: In function ‘int main()’:
boost.cpp:19:59: error: no matching function for call to ‘boost::posix_time::seconds::seconds(double)’
19 | timer.expires_from_now(boost::posix_time::seconds(60.0))
| ^
In file included from /usr/include/boost/date_time/posix_time/posix_time_types.hpp:16,
from /usr/include/boost/asio/time_traits.hpp:23,
from /usr/include/boost/asio/detail/timer_queue_ptime.hpp:22,
from /usr/include/boost/asio/detail/deadline_timer_service.hpp:29,
from /usr/include/boost/asio/basic_deadline_timer.hpp:24,
from /usr/include/boost/asio.hpp:25,
from boost.cpp:1:
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:57:16: note: candidate: ‘template<class T> boost::posix_time::seconds::seconds(const T&, typename boost::enable_if<boost::is_integral<T>, void>::type*)’
57 | explicit seconds(T const& s,
| ^~~~~~~
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:57:16: note: template argument deduction/substitution failed:
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp: In substitution of ‘template<class T> boost::posix_time::seconds::seconds(const T&, typename boost::enable_if<boost::is_integral<T>, void>::type*) [with T = double]’:
boost.cpp:19:59: required from here
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:57:16: error: no type named ‘type’ in ‘struct boost::enable_if<boost::is_integral<double>, void>’
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:53:30: note: candidate: ‘boost::posix_time::seconds::seconds(const boost::posix_time::seconds&)’
53 | class BOOST_SYMBOL_VISIBLE seconds : public time_duration
| ^~~~~~~
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:53:30: note: no known conversion for argument 1 from ‘double’ to ‘const boost::posix_time::seconds&’
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:53:30: note: candidate: ‘boost::posix_time::seconds::seconds(boost::posix_time::seconds&&)’
/usr/include/boost/date_time/posix_time/posix_time_duration.hpp:53:30: note: no known conversion for argument 1 from ‘double’ to ‘boost::posix_time::seconds&&’
What I can think of is the use of the line boost::posix_time::seconds(60.0) is not correct but I am not able to figure out what's the correct way to instantiate the posix_time::seconds class based on the above definitions. Do any of you have an idea about it?
That constructor takes an integral (whole) number. boost::posix_time::seconds(60) should work.
Reference
Related
Compare the following case when I have a class object that takes a vector. The non-deduced parameter T can be substituted fine with the default template argument:
#include <vector>
template <typename T = int>
struct container
{
container(std::vector<T> vec) {}
};
int main()
{
container C = std::vector{1,2,3,4,5};
}
This is not the case for my class which is a bit more complicated (CompilerExplorer):
#include <cstdio>
#include <initializer_list>
#include <variant>
template <size_t> struct obj;
template<size_t Vs>
using val = std::variant<std::monostate, int, struct obj<Vs>>;
template <size_t Vs = 0>
struct obj
{
obj() = default;
obj(std::initializer_list<val<Vs>> init) {
printf("initializer of object called, Vs = %d\n", Vs);
}
};
template <size_t Vs = 0>
struct container : public obj<Vs>
{
container(obj<0> init) {}
};
int main()
{
container<5> some_container = obj{1,2,5,2,obj{1,2,33},2,2};
}
This fails with the following error:
<source>: In function 'int main()':
<source>:29:57: error: class template argument deduction failed:
29 | container<5> some_container = obj{1,2,5,2,obj{1,2,33},2,2};
| ^
<source>:29:57: error: no matching function for call to 'obj(int, int, int)'
<source>:14:5: note: candidate: 'template<long unsigned int Vs> obj(std::initializer_list<std::variant<std::monostate, int, obj<Vs> > >)-> obj<<anonymous> >'
14 | obj(std::initializer_list<val<Vs>> init) {
| ^~~
But it works when I supplement the template specialization obj<0> in the instantiation of the container (in main). Any ideas why this doesn't work for my class and how I can fix it? I don't want to force the user to specify the template each time.
This problem already exists in the simpler case of just
auto o = obj{1,2,33};
which yields this error:
<source>:29:24: error: class template argument deduction failed:
29 | auto o = obj{1,2,33};
| ^
<source>:29:24: error: no matching function for call to 'obj(int, int, int)'
<source>:14:5: note: candidate: 'template<long unsigned int Vs> obj(std::initializer_list<std::variant<std::monostate, int, obj<Vs> > >)-> obj<<anonymous> >'
14 | obj(std::initializer_list<val<Vs>> init) {
| ^~~
<source>:14:5: note: template argument deduction/substitution failed:
<source>:29:24: note: mismatched types 'std::initializer_list<std::variant<std::monostate, int, obj<Vs> > >' and 'int'
29 | auto o = obj{1,2,33};
So, the compiler is unable to deduce, that the three ints should be an initializer list. If you add extra braces around them, the compiler recognizes that this should actually be a single list argument instead of three separate ones and it works:
auto o = obj{{1,2,33}};
This also carries over to the more complicated case:
container some_container = obj{{1,2,5,2,obj{{1,2,33}},2,2}};
The following test program reproduces compilation errors within the context of a larger program:
#include <algorithm>
#include <iostream>
#include <vector>
using std::for_each;
using std::vector;
using std::cout;
using std::endl;
template<typename T, typename C = vector<T>>
class display_container{
public:
display_container(const C& cr):this->cr(cr){this->();}
~display_container(){}
private:
constexpr void operator () (void){if(cr.empty()){cout << "NULL" << " ";} else{for_each(cr.begin(), cr.end(), [](const T& crt){cout << crt << " ";});}}
const C& cr;
};
int main (void){
int n = 5;
vector<int> vec(n, 0);
display_container d(vec);
cout << endl;
return 0;
}
The following is a log of the compiler errors:
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In constructor ‘display_container<T, C>::display_container(const C&)’:
code.cpp:12:40: error: expected identifier before ‘this’
display_container(const C& cr):this->cr(cr){this->();}
^~~~
code.cpp:12:40: error: expected ‘{’ before ‘this’
code.cpp: In function ‘int main()’:
code.cpp:23:28: error: class template argument deduction failed:
display_container d(vec);
^
code.cpp:23:28: error: no matching function for call to ‘display_container(std::vector<int>&)’
code.cpp:12:9: note: candidate: template<class T, class C> display_container(const C&)-> display_container<T, C>
display_container(const C& cr):this->cr(cr){this->();}
^~~~~~~~~~~~~~~~~
code.cpp:12:9: note: template argument deduction/substitution failed:
code.cpp:23:28: note: couldn't deduce template parameter ‘T’
display_container d(vec);
^
code.cpp:10:7: note: candidate: template<class T, class C> display_container(display_container<T, C>)-> display_container<T, C>
class display_container{
^~~~~~~~~~~~~~~~~
code.cpp:10:7: note: template argument deduction/substitution failed:
code.cpp:23:28: note: ‘std::vector<int>’ is not derived from ‘display_container<T, C>’
display_container d(vec);
^
make: *** [makefile:20: code.o] Error 1
I presume that the remaining errors trickle down from the first error related to the inline constructor definition for the display_container template class.
Any suggestions on what is wrong with the code related to inline constructor definition?
TIA
The compiler can not fetch the template type of vector yet:
#include <algorithm>
#include <iostream>
#include <vector>
using std::for_each;
using std::vector;
using std::cout;
using std::endl;
template<typename T, typename C = vector<T>>
class display_container{
public:
display_container(const C& cr): cr(cr) { (*this)(); }
~display_container(){}
private:
constexpr void operator () (void){if(cr.empty()){cout << "NULL" << " ";} else{for_each(cr.begin(), cr.end(), [](const T& crt){cout << crt << " ";});}}
const C& cr;
};
int main (void){
int n = 5;
vector<int> vec(n, 0);
display_container<int> d(vec);
cout << endl;
return 0;
}
You couldn't (and don't need) qualify data members in member initializer list by this, they're expected to be the identifier. The correct syntax should be
display_container(const C& cr):cr(cr){(*this)();}
You should dereference on this and then call operator() on it (as showed abolve), or you can call operator() explicitly like this->operator()(); (which looks ugly).
You should specify the template argument for display_container.
display_container<int> d(vec);
LIVE
Consider the following code:
#include <string>
#include <map>
#include <memory>
#include <utility>
#include <iostream>
typedef std::shared_ptr<const std::string> ConstDataTypePtr;
typedef std::map<std::string, ConstDataTypePtr> StrDataTypeMap;
int main()
{
StrDataTypeMap m_nameToType;
ConstDataTypePtr vp_int8(new std::string("RGH"));
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
return 0;
}
You must compile it with: g++ -std=c++11 <filename>.cpp.
It gives the following error:
testO.cpp: In function ‘int main()’:
testO.cpp:14:88: error: no matching function for call to ‘make_pair(const char [7], ConstDataTypePtr&)’
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
^
testO.cpp:14:88: note: candidate is:
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8.2/bits/char_traits.h:39,
from /usr/include/c++/4.8.2/string:40,
from testO.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
make_pair(_T1&& __x, _T2&& __y)
^
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template argument deduction/substitution failed:
testO.cpp:14:88: note: cannot convert ‘vp_int8’ (type ‘ConstDataTypePtr {aka std::shared_ptr<const std::basic_string<char> >}’) to type ‘std::shared_ptr<const std::basic_string<char> >&&’
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
From what I am reading of the error, the compiler is expecting an r-value when I am trying to insert into the map. Why? What mistake have I made here?
Kindly note that I created this snippet from some existing code which is part of a large code-base. It is probably also worth mentioning that the snippet has been taken from a code base which was run on Windows and I have the task of porting it to Linux. The original author had used std::tr1::shared_ptr. I modified it to use std::shared_ptr. I didn't expect any repercussions because of this change.
The whole point of std::make_pair is to let compiler deduce types. If you want to provide type, use std::pair<K, V>
So
m_nameToType.insert(std::make_pair<std::string, std::string>("int8_t", vp_int8));
should be:
m_nameToType.insert(std::make_pair("int8_t", vp_int8));
or
m_nameToType.insert(std::pair<const std::string, ConstDataTypePtr>("int8_t", vp_int8));
or simply:
m_nameToType.emplace("int8_t", vp_int8);
#include <memory>
#include <map>
#include <string>
int main() {
using shared_data = std::shared_ptr<const std::string>;
std::map<std::string, shared_data> map;
map.insert(std::make_pair(
"something",
shared_data(new std::string("something else"))
));
return 0;
}
see: http://ideone.com/4AQfqd
Back to your problem;
testO.cpp:14:83: note: cannot convert ‘vp_int8’ (type ‘ConstDataTypePtr {aka std::shared_ptr >}’) to type ‘std::basic_string&&’
m_nameToType.insert(std::make_pair("int8_t", vp_int8));
What you have:
std::make_pair<std::string, std::string>(some_string, TOTALLY_NOT_A_STRING)
You gave wrong types to the std::make_pair template. Just change
m_nameToType.insert(std::make_pair<std::string, std::string>("int8_t", vp_int8));
Into
m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>(std::string("int8_t"), vp_int8));
(note the std::make_pair<std::string, ConstDataTypePtr> part)
EDIT: or don't provide template params at all, as someone suggested in comment.
Don't mention the types in the template in make_pair function.
m_nameToType.insert(std::make_pair("int8_t", vp_int8));
Cannot pass function as argument to std::thread when class is defined as template.
compiler: GCC 4.8.2
language: C++11
code:
//---------test.h-----------------------
#ifndef TEST_H
#define TEST_H
#include <iostream>
#include <thread>
using namespace std;
template <class T>
class test
{
public:
test();
void thr(T n);
void testThread();
};
#endif // TEST_H
//---------test.cpp-----------------------
#include "test.h"
template <class T>
test<T>::test()
{
}
template <class T>
void test<T>::thr(T n)
{
cout << n << endl;
}
template <class T>
void test<T>::testThread()
{
T n = 8;
thread t(thr, n);
t.join();
}
//---------main.cpp-----------------------
#include <iostream>
using namespace std;
#include "test.h"
#include "test.cpp"
int main()
{
test<double> tt;
tt.testThread();
return 0;
}
compiler error:
In file included from ../std_threads/main.cpp:5:0:
../std_threads/test.cpp: In instantiation of 'void test<T>::testThread() [with T = double]':
../std_threads/main.cpp:10:19: required from here
../std_threads/test.cpp:19:20: error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, double&)'
thread t(thr, n);
^
../std_threads/test.cpp:19:20: note: candidates are:
In file included from ../std_threads/test.h:4:0,
from ../std_threads/main.cpp:4:
/usr/include/c++/4.8.2/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (test<double>::*)(double); _Args = {double&}]
thread(_Callable&& __f, _Args&&... __args)
^
/usr/include/c++/4.8.2/thread:133:7: note: no known conversion for argument 1 from '<unresolved overloaded function type>' to 'void (test<double>::*&&)(double)'
/usr/include/c++/4.8.2/thread:128:5: note: std::thread::thread(std::thread&&)
thread(thread&& __t) noexcept
^
/usr/include/c++/4.8.2/thread:128:5: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.8.2/thread:122:5: note: std::thread::thread()
thread() noexcept = default;
^
/usr/include/c++/4.8.2/thread:122:5: note: candidate expects 0 arguments, 2 provided
make: *** [main.o] Error 1
20:48:35: The process "/usr/bin/make" exited with code 2.
Error while building/deploying project std_threads (kit: Desktop)
When executing step 'Make'
You need to fully specify the member function name and pass an argument for the implicit first parameter of the non-static member function:
thread t(&test<T>::thr, this, n);
See std::thread of a member function.
Two problems:
to get a pointer to a member function, you need to use & and qualify the function name with the class name. Member functions names don't convert to pointers in the same way as non-member function names.
member functions need an object to act on.
So in this case, you probably want
thread t(&test<T>::thr, this, n);
I took the code from
http://www.boost.org/doc/libs/1_54_0/libs/graph/doc/edge_list.html
included my header,
#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/edge_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/bellman_ford_shortest_paths.hpp>
#include <boost/graph/johnson_all_pairs_shortest.hpp>
#include <fstream>
#include <ctime>
using namespace boost;
int main(){
enum { u, v, x, y, z, N };
char name[] = { 'u', 'v', 'x', 'y', 'z' };
typedef std::pair<int,int> E;
E edges[] = { E(u,y), E(u,x), E(u,v),
E(v,u),
E(x,y), E(x,v),
E(y,v), E(y,z),
E(z,u), E(z,x) };
int weight[] = { -4, 8, 5,
-2,
9, -3,
7, 2,
6, 7 };
typedef boost::edge_list<E*> Graph;
Graph g(edges, edges + sizeof(edges) / sizeof(E));
std::vector<int> distance(N, std::numeric_limits<short>::max());
std::vector<int> parent(N,-1);
distance[z] = 0;
parent[z] = z;
bool r = boost::bellman_ford_shortest_paths(g, int(N), weight,
distance.begin(),
parent.begin());
if (r)
for (int i = 0; i < N; ++i)
std::cout << name[i] << ": " << distance[i]
<< " " << name[parent[i]] << std::endl;
else
std::cout << "negative cycle" << std::endl;
return 0;
}
compile with
g++ -O3 boostexampl.cpp -I/user/include/
I got this error
make -k
g++ -O3 boostexampl.cpp -I/user/include/
boostexampl.cpp: In function ‘int main()’:
boostexampl.cpp:40:61: error: no matching function for call to ‘bellman_ford_shortest_paths(Graph&, int, int [10], std::vector<int>::iterator, std::vector<int>::iterator)’
boostexampl.cpp:40:61: note: candidates are:
In file included from boostexampl.cpp:7:0:
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:91:8: note: template<class EdgeListGraph, class Size, class WeightMap, class PredecessorMap, class DistanceMap, class BinaryFunction, class BinaryPredicate, class BellmanFordVisitor> bool boost::bellman_ford_shortest_paths(EdgeListGraph&, Size, WeightMap, PredecessorMap, DistanceMap, BinaryFunction, BinaryPredicate, BellmanFordVisitor)
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:91:8: note: template argument deduction/substitution failed:
boostexampl.cpp:40:61: note: candidate expects 8 arguments, 5 provided
In file included from boostexampl.cpp:7:0:
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:210:8: note: template<class EdgeListGraph, class Size, class P, class T, class R> bool boost::bellman_ford_shortest_paths(EdgeListGraph&, Size, const boost::bgl_named_params<P, T, R>&)
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:210:8: note: template argument deduction/substitution failed:
boostexampl.cpp:40:61: note: mismatched types ‘const boost::bgl_named_params<P, T, R>’ and ‘int [10]’
In file included from boostexampl.cpp:7:0:
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:222:8: note: template<class EdgeListGraph, class Size> bool boost::bellman_ford_shortest_paths(EdgeListGraph&, Size)
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:222:8: note: template argument deduction/substitution failed:
boostexampl.cpp:40:61: note: candidate expects 2 arguments, 5 provided
In file included from boostexampl.cpp:7:0:
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:229:8: note: template<class VertexAndEdgeListGraph, class P, class T, class R> bool boost::bellman_ford_shortest_paths(VertexAndEdgeListGraph&, const boost::bgl_named_params<T, Tag, Base>&)
/usr/local/include/boost/graph/bellman_ford_shortest_paths.hpp:229:8: note: template argument deduction/substitution failed:
boostexampl.cpp:40:61: note: mismatched types ‘const boost::bgl_named_params<T, Tag, Base>’ and ‘int’
make: *** [examp] Error 1
make: Target `main' not remade because of errors.
Compilation exited abnormally with code 2 at Sat Oct 5 14:24:35
I am kind of stuck here. Any help would be appreciated. Sorry I provides the full code, but I don't know where is problem is. Is boost examples guaranteed to work? did they change the interface but didn't change on-line example? Or I didn't include headers.