This is on os x yosemite with clang from xcode 7.2 in clion.
I'm iterating through a query from a postgresql db and adding the result to a json object.
for (pqxx::result::const_iterator c = R.begin(); c != R.end(); ++c) {
participants["participants"] += { \
{"id", c[0].as<std::string>()},
{"location", c[1].as<std::string>()},
{"racename", c[2].as<std::string>()},
{"racestart_at", c[3].as<std::string>()},
{"ended_at", static_cast<bool>(c[9].size()) ? c[9].as<std::string>() : ""},
{"racetime", static_cast<bool>(c[10].size()) ? c[10].as<std::string>() : ""}
};
}
Some of the columns have null values so I test for that casting to bool in a ternary operator and either return the result or an empty string. To make it a bit cleaner I tried to add a template function with the example from http://www.cprogramming.com/tutorial/templated_functions.html and had this:
template <class T>
std::string column_content(T a) {
return static_cast<bool>(a.size()) ? a.as<std::string>() : "";
}
When I try to compile the program I get the error:
Database.cpp:9:44: error: use 'template' keyword to treat 'as' as a dependent template name
return static_cast<bool>(a.size()) ? a.as<std::string>() : "";
^
template
I looked at Cast Chars To Int in Template Function and http://www.cplusplus.com/doc/oldtutorial/templates/ and other suggestions from google but it looks like I'm using the wrong syntax but I can't spot it.
If I could use a template function adding to json could then look like
{"start_at", column_content(c[8])}
regards
Claus
I changed it to a function for the time being. The type passed is pqxx::result::field as per http://pqxx.org/devprojects/libpqxx/doc/2.6.9/html/Reference/a00259.html#2a9d36599b217ebfde2cac4633856ac0.
std::string column_content(pqxx::result::field a) {
if (static_cast<bool>(a.size())) {
return a.as<std::string>();
} else {
return "";
}
}
Related
I have a function that receives a const reference and I need to call a template library function using this reference:
std::vector<cv::Size> get_resolutions(const rs2::device& dev)
{
auto sensor = dev.first<rs2::depth_sensor>();
//more code
}
class device
{
public:
template<class T>
T first()
{
for (auto&& s : query_sensors())
{
if (auto t = s.as<T>()) return t;
}
throw rs2::error("Could not find requested sensor type!");
}
//more code
};
When I compile with gcc I get this error:
error: passing 'const rs2::device' as 'this' argument discards qualifiers [-fpermissive]
I can't change the first() function as it's part of a external library (librealsense, line 51 in here).
I can't remove the const from the function argument dev because that will result in removing const correctness in a lot of places.
I can overcome the error by removing the const from dev:
auto sensor = const_cast<rs2::device&>(dev).first<rs2::depth_sensor>();
However, this feels bad practice. Is there any more correct way of dealing with this error? I have tried unsuccessfully the following variations:
auto sensor = dev.first<const rs2::depth_sensor>();
auto sensor = const_cast<const rs2::depth_sensor>(dev.first<rs2::depth_sensor>());
but I get the same error with them.
I think there are two possible solutions to this. Either you allow get_resolutions to take dev by non-const reference (although that may require you to modify code at the call site), or you re-implement first yourself.
Option 1
Just replace
std::vector<cv::Size> get_resolutions(const rs2::device& dev)
with
std::vector<cv::Size> get_resolutions(rs2::device& dev)
This, however, would also mean that you can no longer call get_resolutions with a temporary object.
Option 2
Looking at the source of the library, however, I really can't see why first() is non-const. All it does is call query_sensors() (which is const-qualified, and also public), and process the results:1
template<class T>
T first()
{
for (auto&& s : query_sensors())
{
if (auto t = s.as<T>()) return t;
}
throw rs2::error("Could not find requested sensor type!");
}
This might be the option with the lowest impact: Just define a first() yourself, outside of the library, that replicates this functionality:
template <class T>
T custom_first(const rs2::device& dev)
{
for (auto&& s : dev.query_sensors())
if (auto t = s.as<T>())
return t;
throw rs2::error("Could not find requested sensor type!");
}
1 Time to file a bug report, maybe?
I am trying use a variadic template in an && statement, but i dont know how to actually do it. Can somebody explain to me how i can programm a function like this one:
using EntitySet = std::vector<Entity>;
template<typename... TArgs>
EntitySet getEntitesWith()
{
EntitySet entitySet;
for(const Entity& entity : m_entitySet)
{
if (entity.hasComponent<T1>() && entity.hasComponent<T2>() && ...)
{
entitySet.push_back(entity);
}
}
return entitySet;
}
entity.hasComponent<>() returns true if the entity has a Component of the type that is passed into the function
Edit:
i just tried the Fold Expression in c++17 and when i tried to do it like #Igor Tandetnik and #oisyn told me to i got an Unexpected ... Token Error.
But when i wrote the code like this:
if (( ... && entity.hasComponent<TArgs>()))
With an extra () i got an internal compiler error and have no idea on what im doing wrong.
anybody have an idea on why this is happening?
I have a templated function similar to:
template<class T>
T foo( string sReturnType )
{
//pseudo code
if( sReturnType = "string" )
{
lookup data in string table
return a string
}
else
{
look up in number table
return number answer
}
}
usage would be something like: foo("string")
inside the function, there needs to be logic that either pulls from a string table or a number table and returns that value. I played around with this and wasn't able to get it to work as I expected. It seems like it should be pretty straight forward and easy to do. Is this a valid approach and use of templates? I looked at template specialization but then you end up writing two separate code bases anyways, why not use an overloaded function? Is there a better way?
No - there is no way to declare a function having different return types (A template function may have different return types, but these would depend on a template parameter).
You could return a type encapsulating all possible return types (like boost::any or boost::variant) instead.
You have to overload foo(); There's pretty much no way around it.
std::string foo( std::string )
{
// look up data...
return std::string();
}
int foo( int )
{
// look up data...
return -1;
}
int i = foo( 1 );
std::string s = foo( "string" );
I have this enum (class)
enum class conditional_operator
{
plus_op,
or_op,
not_op
}
And I'd like a std::map that represents these mappings:
std::map<conditional_operator, std::binary_function<bool,bool,bool>> conditional_map =
{ { conditional_operator::plus_op, std::logical_and<bool> },
{ conditional_operator::or_op, std::logical_or<bool>},
{ conditional_operator::not_op, std::binary_negate<bool>} // this seems fishy too, binary_negate is not really what I want :(
Apart from the fact that this doesn't compile:
error: expected primary-expression before '}' token
error: expected primary-expression before '}' token
error: expected primary-expression before '}' token
for each of the three lines, how should I do this? I think a logical_not with a second dummy argument would work, once I get this to compile of course...
EDIT: Could I use lambda's for this?
You really want std::function<bool(bool, bool)>, not std::binary_function<bool, bool, bool>. That only exists for typedefs and stuff in C++03. Secondly, I'd just use a lambda- they're short enough and much clearer. The std::logical_and and stuff only exists for C++03 function object creation, and I'd use a lambda over them any day.
std::map<conditional_operator, std::function<bool(bool,bool)>> conditional_map =
{
{ conditional_operator::plus_op, [](bool a, bool b) { return a && b; } },
{ conditional_operator::or_op, [](bool a, bool b) { return a || b; } },
{ conditional_operator::not_op, [](bool a, bool b) { return !a; } }
};
Wait- what exact operator are you referring to with not? Because that's unary, as far as I know.
#DeadMG’s answer is spot-on but if you insist on using the predefined function objects, you need to instantiate them. At the moment you’re just passing their type names.
That is, you need to write std::logical_***<bool>() instead of just std::logical_***<bool>.
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);
}