I have a struct defined as:
template<typename T>
struct unique_owned_item_filter: public std::unary_function<T,bool> {
unique_owned_item_filter(){}
bool operator()(const T& item)const {
return !item->shared() || item->owner() == MPI::COMM_WORLD.Get_rank();
}
typedef T item_type;
};
and I want to use this structure in a function like this
void read_nodes(std::ifstream& infile, mesh_type& mesh, const std::list<int>&my_nodes)
{
typedef typename mesh_type::node_t nd_t;
..... follows some code .....
create_double_nodes(mesh,unique_owned_item_filter<nd_t>);
}
where the function create_double_nodes is defined as
template<typename mesh_type, typename rule_type >
void create_double_nodes(mesh_type& mesh,rule_type& rule){
.... follows some code ....
}
When I pass to create_double_nodes the argument unique_owned_item_filter I insert
its dependence on the template parameter nd_t, that, in my case, is the mesh node
of type mesh_type::node_t.
When I compile the whole, I get the error expected primary-expression before ')' token at the declaration of create_double_nodes(mesh,unique_owned_item_filter<nd_t>);.
It seems to me that the template argument is right.
Can somebody help me?
The problem in the definition of the create_double_nodes disappeared, but now the problem appeared inside the body of the function itself.
template<typename mesh_type, typename rule_type >
void create_double_nodes(mesh_type& mesh, const rule_type& rule){
typename mesh_type::nd_set_t::const_iterator it_first( mesh.nodes().begin());
while(it_first!=mesh.nodes().end()){
if(rule(*it_first))
....follows code ....
it_first++
}
when i apply the rule to the const iterator it does not accept it. The compilation gives the following error:
no match for call to '(const GALES::unique_owned_item_filter, 5, GALES::base_5_dofs> >) (GALES::fem_node, 5, GALES::base_5_dofs>* const&)'
with candidates
bool GALES::unique_owned_item_filter<T>::operator()(const T&) const [with T = GALES::fem_node<GALES::geometric_node<2>, 5, GALES::base_5_dofs>]
where
GALES::fem_node<GALES::geometric_node<2>, 5, GALES::base_5_dofs>
is the complete type of node of the mesh.
I cannot understand why the rule applied to a constant iterator is not accepted. If you need more details I will try to explain it better.
Thank you very much again.
unique_owned_item_filter<nd_t> is a type, but you're using it as a function argument, where a value is required. You probably wanted to create an object of this type instead:
create_double_nodes(mesh, unique_owned_item_filter<nd_t>());
// ^^ parens here!
This will not work as-is, though, because your function template create_double_nodes takes the second parameter by non-const reference, and such cannot bind to a temporary (such as the one created in my example above).
You have two solutions: either change create_double_nodes to take its parameter by const-reference, or create a named object for the argument:
unique_owned_item_filter<nd_t> filter;
create_double_nodes(mesh, filter);
1.Make it an object:
create_double_nodes(mesh,unique_owned_item_filter<nd_t>());
^^
2.Pass by const reference or value:
void create_double_nodes(mesh_type& mesh, const rule_type& rule){
^^^^^
Related
Suppose I have the following functions:
static bool fun1(IOPin* obj) { }
static bool fun2(IOPin* obj, const bool& arg) { }
I want to be able to store pointers pointing to each of these functions in an array, something like:
template<typename ...Args>
static bool (*callbacks[2])(IOPin*, const Args&...){nullptr};
callbacks[0] = &fun1;
callbacks[1] = &fun2;
However, a couple of errors arise:
1 - when assigning "fun1"
callbacks[0] = &fun1;
I get the following compile time error:
error: missing template arguments before '[' token
So, I have the questions: How to explicitly pass "no template arguments". Since no variadic arguments were passed, is it okay to use:
callbacks<void>[0] = &fun1;
However, doing this, causes the following compile time error:
error: forming reference to void
static bool (*callbacks[2])(IOPin *obj, const Args&...){nullptr};
^~~~~~~~~
2 - Also, if I try to assign "fun2":
callbacks<bool>[1] = &fun2;
I get the following compile time error:
undefined reference to `callbacks<bool>'
What am I missinterpreting or how are my concepts bad here?
Thanks in advance
I want to detect at compile time if a given type has the pre-increment operator with the library fundamentals TS v2 type_traits' is_detected_exact helper - however, it seems like I either misunderstood this helper or I supplied the wrong parameters, the following code does not compile:
#include <experimental/type_traits>
template<typename T>
using operator_plusplus_t = decltype(&T::operator++);
template<typename T>
using has_pre_increment = std::experimental::is_detected_exact<T&, operator_plusplus_t, T>;
struct incrementer
{
incrementer& operator++() { return *this; };
};
static_assert(has_pre_increment<incrementer>::value, "type does not have pre increment");
The error I get is this one (the static_assert fails):
<source>:14:15: error: static assertion failed: type does not have pre increment
static_assert(has_pre_increment<incrementer>::value, "type does not have pre increment");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Compiler returned: 1
https://godbolt.org/z/-zoUd9
I was expecting this code to compile since the "incrementer" struct has a operator++ method with no arguments returning a reference to its type ...
Maybe you can point me in the right direction, thanks in advance!
You can use decltype(++std::declval<T>()) instead.
https://godbolt.org/z/h_INw-
So I'm attempting to utilize a generic compare functor in my utility class.
I attempt to define it and call it like so
template <class T>
bool AVL_tree<T>::avl_insert(AVL_Node<T> *& top, const AVL_Node<T> * insertNode, bool & taller) {
std::binary_function<T,T,bool>::first_argument_type insertNodeValue;
insertNodeValue = insertNode->data;
std::binary_function<T,T,bool>::second_argument_type topValue;
topValue = insertNode->data;
std::binary_function<T,T,bool>::result_type cmp_result;
cmp_result = comparer(insertNodeValue,topValue);
std::binary_function<T,T,bool>::result_type cmp_result2;
cmp_result2 = comparer(topValue,insertNodeValue);
//Function continues from here
}
The specific compiler error is expected ; before insertNodeValue
This error is repeated for topValue and cmp_result;
I don't really understand why this is a syntax error, I'm working off this reference:
http://www.cplusplus.com/reference/std/functional/binary_function/
It's a dependent name, so it requires the typename keyword:
typename std::binary_function<T,T,bool>::first_argument_type insertNodeValue;
Similarly for others. See the SO FAQ entry on dependent names.
Given that these are dependent types, your first step should probably be to add typename:
typename std::binary_function<T,T,bool>::first_argument_type insertNodeValue;
I can't figure out whats wrong with the code here, so I was hopinh someone could help me out:
In a header file, I define the following functions
void GenLiveVar(const instr_ptr instr, std::vector<ResultBase*> &list);
void KillLiveVar(const instr_ptr instr, std::vector<ResultBase*> &list);
In a class header file, I define this typedef:
typedef boost::function<void(instr_ptr, std::vector<ResultBase*>) > GenFunction;
inside the class, I have two instances of GenFunction
GenFunction Gen;
GenFunction Kill;
And I assign into them as follows
void DataFlowSolver::SetGenFunction(GenFunction &func)
{
Gen = func;
}
void DataFlowSolver::SetKillFunction(GenFunction &func)
{
Kill = func;
}
later in my program, I assign to gen as follows:
blockSolver.SetGenFunction(GenLiveVar);
where GenLiveVar is the function mentioned earlier and blockSolver is an instance of the class holding the Gen/Kill. Inside blockSolver, I do the following:
std::vector<ResultBase*> genList;
Gen(currentBlock->GetInstrPtr(i), &genList);
and GetInstrPtr is defined as const instr_ptr GetInstrPtr(int index);
It generates the follwoing error (sorry for length)
no match for call to '(GenFunction) (const instr_ptr, std::vector<ResultBase*, std::allocator<ResultBase*> >*)'
/nfs/ug/homes-2/r/rileyjon/ece540/Final/boost/function/function_template.hpp:1007:
note: candidates are: typename boost::function2<R, T1, T2>::result_type boost::function2<R, T1, T2>::operator()(T0, T1) const [with R = void, T0 = boost::shared_ptr<Instruction>,
T1 = std::vector<ResultBase*, std::allocator<ResultBase*> >
]
I dont really understand why this is a problem: the types are definitely the same. Some help would be appreciated. Thanks
The types are definitely not the same.
The argument you are passing is of type std::vector<ResultBase*>* (a pointer):
Gen(currentBlock->GetInstrPtr(i), &genList);
^
The corresponding parameter is of type std::vector<ResultBase*> (a value):
boost::function<void(instr_ptr, std::vector<ResultBase*>)>
^
Also note the mismatch in parameter types between the boost::function, which takes the second argument by value, and the two functions you assign to it, which take their second arguments by reference. This probably won't give you the behavior you expect.
I have one template function which will take a pointer type and i have instantiated it before calling.
i have written function with its dummy implementation as follows:
template<T>fun_name( const T *p )
{
//written functionality which will give me class name that i will store into string Variable
e.g. i got output like this string Var = "First_class" or string Var = "Second_class"
//Using this class name i will call one function of that class
if(Var == "Fisrt_class")
{
First_class::static_function_name(p);
}
if(Var == "Second_class")
{
Second_class::static_function_name(p);
}
}
and in global scope i instantiated this function for two variables as like below:
template<first_class>static_function_name(const First_class *)
template<Second_class>static_function_name(const Second_class *)
above code gives me error that
error: no matching function call in Second_class::static_function_class(const Fisrt_class*)
error: no matching function call in First_class::static_function_class(const Second_class*)
thanks in advance!
I think this :
template<typename T> // template<class T> is equally valid!
void fun_name( const T *p )
{
T::static_function_name(p);
}
is enough!
Two more errors is fixed in the above code:
Mention the keyword typename in template<T> in your code. You can also write template<class T> which is equally valid.
Mention the return type of the function template as well.
Your function template "calls" each of the static functions in each class. Even though program flow may never get to one of the calls, the compiler still has to figure out the code for each of them.
So when you instantiate:
template<first_class>fun_name(const first_class*)
the compiler tries to compile the entire function with T = first_class, which means at some point inside the function, it will try to compile the function call:
Second_class::static_function_name(p);
But since variable p is a pointer to first_class, the compiler doesn't find the function.
If you want conditional compilation, try specializing your function instead so the compiler only compiles the function call you intended for each type:
template <T> fun_name (const T* p);
template <> fun_name<first_class>(const first_class* p) {
first_class::static_function_name(p);
}
template <> fun_name<second_class>(const second_class* p) {
second_class::static_function_name(p);
}
Alternatively, you can use member functions which seem to be intended for what you are trying to do here. Then you can create objects and call the functions directly:
first_class f;
second_class s;
f.function();
s.function();
try changing to ,
template<typename T>
void fun_name( const T *p )
{
T::static_function_name(p);
}