I want to handle template arguments diffrently so for the code:
template <class T> class A {
public:
A() {}
};
void faa(A<int>& param);
I would like to know that param is a template specialisation and get access it's parameters.
So I wrote an ASTVisitor with function
bool VisitFunctionDecl(FunctionDecl *f) {
std::cout<< "VisitFunctionDecl" <<std::endl;
const DependentTemplateSpecializationType* t1;
const TemplateSpecializationType* t2;
for(ParmVarDecl* p :f->params())
{
t1=p->getType()->getAs<DependentTemplateSpecializationType>();
t2=p->getType()->getAs<TemplateSpecializationType>();
if(t1!=nullptr||t2!=nullptr)
{
std::cout<< "template param found" <<std::endl;
}
}
return true;
}
But those casts are both nullptr always - I never get the template param found output.
What am I doing wrong? Is there any other way to cast t to some king of type allowing checking of the template parameters?
Type of A<int>& is LValueReference (can be checked with getTypeClassName()). What you are probably trying to get is type pointed by reference. You can get it with getNonReferenceType() method.
bool VisitFunctionDecl(FunctionDecl *f) {
llvm::errs() << "VisitFunctionDecl:" << f->getQualifiedNameAsString()
<< "\n";
for (ParmVarDecl* p : f->params()) {
llvm::errs() << p->getType().getAsString() << " -> "
<< p->getType()->getTypeClassName() << "\n";
llvm::errs() << "isPointerType: "
<< p->getType()->hasPointerRepresentation() << "\n"
<< "isTemplateSpecialization: "
<< (nullptr != p->getType().getNonReferenceType()->getAs<
TemplateSpecializationType>()) << "\n";
}
return true;
}
output is:
VisitFunctionDecl:faa
const A<int> & -> LValueReference
isPointerType: 1
isTemplateSpecialization: 1
Related
#include <iostream>
using namespace std;
template<class KeyT, class ValueT>
struct KeyValuePair {
const KeyT &key_;
const ValueT &value_;
KeyValuePair() {
cout << "KeyValuePair() constructor" << endl;
}
KeyValuePair( const KeyValuePair<KeyT, ValueT> &other) {
cout << "KeyvaluePiar copy constructor" << endl;
}
KeyValuePair(KeyT key, ValueT value) : key_(key), value_(value) {
cout << "KeyValuePair(KeyT, ValueT) constructor" << " key_: " << key_ << " value_ " << value_ << endl;
}
~KeyValuePair() {}
};
struct foo {
int i;
};
void dump(const KeyValuePair<int, foo*> &kp) {
//printf("dump printf key: %d, value: %p\n", kp.key_, kp.value_);
cout << "dump cout key_: " << kp.key_ << " value_: " << kp.value_ << " i: " << (kp.value_)->i << "\n";
}
int main() {
cout << "test kv\n";
foo *ptr = new foo();
ptr->i = 3000;
printf("address of ptr: %p\n", ptr);
dump(KeyValuePair<int, foo*>(10, ptr));
return 0;
}
Run it with
g++ -g -std=c++11 -fPIC -O0 -o main main.cc && ./main
on a Linux machine.
In the above c++ example code gives the following result
test kv
address of ptr: 0x18a1010
KeyValuePair(KeyT, ValueT) constructor key_: 10 value_ 0x18a1010
dump cout key_: 10 value_: 0x7fffae060070 i: -1375338428
It seems that KeyValuePair's value_ is messed up after calling dump function, anyone knows the reason? It seems to be related to reference and pointers.
Your member variable is a reference:
const KeyT &key_;
Your constructor, on the other hand, passes by value:
KeyValuePair(KeyT key, ValueT value)
That means you are storing a reference to a temporary variable that will get destroyed almost immediately.
One solution would be to pass by reference in your constructor:
KeyValuePair(KeyT& key, ValueT& value)
which is better, but not perfect, since you pass a int literal 10 into the function.
If you really just need a pair, the best solution is probably to use std::pair.
I have a variable x.
It may either be of type char, uint8_t or std::string.
I wish to output the number (not character), using the same expression involving std::cout. This is because I use this expression in generated code.
At code-generation-time, I currently don't know if x will be char, uint8_t or std::string.
std::cout << x << std::endl does not work if x is of type char, since it will output the character and not the number.
std::cout << +x << std::endl does not work if x is of type std::string.
std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? +x : x) << std::endl does not work if x is of type std::string.
std::cout << (typeid(x) == typeid(uint8_t) || typeid(x) == typeid(char) ? static_cast<int>(x) : x) << std::endl does not work if x is of type std::string.
I am aware that std::cout can be configured in various ways by piping std::hex or std::boolalpha, but I know of no possible way to configure std::cout to output a char as a number, without casting the char first.
Is there a way to use reflection, operator overloading, templates or something else
so that one can have a single unified statement for outputting x, as a number?
For example, if x is 65 with type char, the desired output is 65, not A.
Just format a helper and specialize the versions you want to customize appropriately. For example:
#include <iostream>
template <typename T>
struct formatter {
T const& value;
};
template <typename T>
formatter<T> format(T const& value) {
return formatter<T>{value};
}
template <typename T>
std::ostream& operator<< (std::ostream& out, formatter<T> const& v) {
return out << v.value;
}
std::ostream& operator<< (std::ostream& out, formatter<char> const& v) {
return out << int(v.value);
}
template <std::size_t N>
std::ostream& operator<< (std::ostream& out, formatter<char[N]> const& v) {
return out << '\'' << v.value << '\'';
}
int main() {
std::cout << "char=" << format('c') << " "
<< "int=" << format(17) << " "
<< "string=" << format("foo") << " "
<< "\n";
}
I guess you are working within generic context. So your basic problem is that you need static dispatch. The trigraph operator ? : does not provide this. it is evaluated at run time and will always invoke the same operator<<.
So you have two options:
use a helper class with partial specialization.
use static if. I.e.:
if constexpr (std::is_integral<decltype(x)>::value)
std::cout << static_cast<int>(x) << std::endl;
else
std::cout << x << std::endl;
The latter requires C++17.
This solution worked for me. It outputs the char as a number by using the output function together with template specialization and if constexpr:
#include <cstdint>
#include <iostream>
#include <string>
using namespace std::string_literals;
template <typename T> void output(std::ostream& out, T x)
{
if constexpr (std::is_integral<decltype(x)>::value) {
out << static_cast<int>(x);
} else {
out << x;
}
}
int main()
{
char x = 65;
uint8_t y = 66;
std::string z = "hi"s;
// output: A
std::cout << x << std::endl;
// output: 65
output(std::cout, x);
std::cout << std::endl;
// output: B
std::cout << y << std::endl;
// output: 66
output(std::cout, y);
std::cout << std::endl;
// output: "hi"
output(std::cout, z);
std::cout << std::endl;
return 0;
}
Thanks to Dietmar Kühl and Marcel for the helpful answers.
Let's say I want to print the number args if they are > 1 or "none" if they are <= 1. The only way I know how to do this is:
cout << "number of args: ";
if (argc > 1)
cout << argc - 1;
else
cout << "none";
cout << endl;
But then I can't chain the << operator. Ideally, I would like to be able to do something like:
cout << "number of args: "
<< argc > 1 ? argc - 1 : "none"
<< endl;
But this isn't possible because the types from a ternary if are different.
Ideas?
The simple way. Handle with a string.
std::cout << "number of args: "
<< (argc > 1 ? std::to_string(argc - 1) : "none")
<< std::endl;
It has some superfluous cost to change the string. But it is easy to read and maintain if it is used once. And the reason the parentheses are required is that the shift operator(<<) has higher precedence than ternary conditional operator(?:) or relational operators (>).
You can make your own class to do the limit printing:
class limit {
int lim;
int k;
public:
limit(int lim_, int k_) : lim(lim_), k(k_) {}
friend ostream& operator<<(ostream& ostr, const limit& lim);
};
ostream& operator<<(ostream& ostr, const limit& lim) {
if (lim.k < lim.lim) {
ostr << "none";
} else {
ostr << lim.k - lim.lim;
}
return ostr;
}
int main() {
cout << "Hello " << limit(1, 15) << endl;
cout << "World " << limit(1, -1) << endl;
return 0;
}
Demo.
The limit class holds two numbers - the limit (1 in the demo) and the number to be printed. It provides an operator << for printing, which uses your conditional statement to print either the value over the limit, or "none". This lets you write cout << limit(1, argc), and produce the desired printout.
If you place the << within the ternary expressions, it unifies the types for both the true and false cases.
argc > 1 ? std::cout << argc - 1 : std::cout << "none";
You can use a helper template function to make things a bit more seamless:
template <typename T>
std::ostream & argp (const T &x) {
return std::cout << "number of args: " << x;
}
(argc > 1 ? argp(argc - 1) : argp("none")) << std::endl;
If you want a more general solution, you could create a (template) class that stores references to two objects and a bool. Then overload operator<< to choose which member to print based on the bool.
template<typename T, typename U>
class be_careful_this_class_holds_references_to_its_constructor_arguments
{
public:
be_careful_this_class_holds_references_to_its_constructor_arguments(
bool b, T const& t, U const& u)
:choose_first(b), first(t), second(u)
{}
friend std::ostream& operator<<(
std::ostream& os,
be_careful_this_class_holds_references_to_its_constructor_arguments const& p)
{
if (p.choose_first)
os << p.first;
else
os << p.second;
return os;
}
private:
bool choose_first;
T const& first;
U const& second;
};
Using this class is a bit cumbersome though, you have to name the types. You can fix that with a helper function:
template<typename T, typename U>
be_careful_this_class_holds_references_to_its_constructor_arguments<T,U>
pick(bool choice, T const& first, U const& second)
{
return be_careful_this_class_holds_references_to_its_constructor_arguments<T,U>(choice,first,second);
}
Then you can just call this function, passing a condition to the first parameter, and your two options of what to print to the second and third parameters:
std::cout << pick(argc > 1, argc - 1, "none") << std::endl;
Just for the sake of adding to the existing craziness....
Eventual usage supported:
xstream xs(std::cout) << If(argc <= 1) << argc - 1 << _else << "none" << _endif << '\n';
Note that this does not short-circuit evaluation of the "if" or "else" branches the way ?, : and ; does, but it doesn't require a conversion to a common type either....
Implementation (also at ideone.com.
#include <iostream>
using namespace std;
struct If { If(bool active) : active_(active) { } bool active_; };
struct Else { } _else;
struct Endif { } _endif;
class xstream
{
public:
xstream(std::ostream& os) : os_(os) { }
template <typename T>
friend xstream& operator<<(xstream& s, const T& t)
{
if (s.active_) s.os_ << t;
return s;
}
private:
bool active_;
std::ostream& os_;
};
template <>
xstream& operator<< <If>(xstream& s, const If& _if)
{
s.active_ = _if.active_;
return s;
}
template <>
xstream& operator<<<Else>(xstream& s, const Else& _else)
{
s.active_ ^= true;
return s;
}
template <>
xstream& operator<<<Endif>(xstream& s, const Endif& _endif)
{
s.active_ = true;
return s;
}
int main(int argc, const char* argv[])
{
xstream xs(std::cout);
xs << If(argc <= 1) << argc - 1 << _else << "none" << _endif << '\n';
}
(Note that the xstream constructor only keeps a reference to the stream it's controlling, so the latter's lifetime must outlive the former's use under penalty of undefined behaviour).
I'm trying to create a relatively type safe(but dynamic) and efficient concept called "Linkable Properties". A linkable property is similar to C#'s ability to bind properties and such and similar to the signal/slot model.
A linkable property is a type that can link itself to the values of other types. When any value changes all values are updated. This is useful when you need to keep several properties/values updated simultaneously. Once you setup a link everything is taken care of for you.
Can link from any type to any other type (in theory, this is the issue)
Links use a linked list rather than a list. This is more efficient both memory and speed and the real benefit of using this approach.
Converters are used to convert the values from one type to another(from 1, required, also an issue)
Can act like a getter and setter.
The issues I'm struggling with is writing the ability to link and convert to any type. The following code works with minor changes(convert the templated Chain function to a non-templated version and Change Chain<F> to Chain in the SetLink function). The problem is, the links are not correctly called.
This class almost works(it does compile and run but does not work as expected. Without the changes above the binding function never calls. It is only test code and not properly coded(please don't comment about using the static counter, it's just a temporary fix). The Chain and Link elements are the crucial aspect.
Chain is simply suppose to convert and update the value of the property then pass it along(or possibly the original value) to the next property. This continues until one reaches back to the original property in which case it will terminate.
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
static int iLCount = 1;
template <typename T>
class LinkableProperty
{
public:
std::string Name;
boost::function<void(T)> Link;
T Value;
template<typename F>
void Chain(F val)
{
Value = val;
std::cout << this->Name << " - " << this << ", " << &Link << ", " << val << " ! " << this->Value << " - " << "\n";
if (--iLCount < 0) return;
if (!Link.empty()) Link(Value);
}
LinkableProperty() { Link = NULL; Value = T(); Name = "Level " + std::to_string(iLCount++); };
void operator =(T value) { Value = value; }
template<typename F> void SetLink(LinkableProperty<F> &p)
{
Link = boost::bind(&LinkableProperty<F>::template Chain<F>, &p, _1);
}
void operator ()()
{
if (!Link.empty()) Link(Value);
}
};
int main()
{
LinkableProperty<unsigned short> L1;
LinkableProperty<double> L2;
L2.SetLink(L1);
L1.SetLink(L2);
L1 = 1;
L2 = 1.1;
L1();
cout << "----------\n" << L1.Value << ", " << L2.Value << endl;
getchar();
return 0;
}
The problem most likely stems from here:
template<typename F> void SetLink(LinkableProperty<F> p)
You are passing in a copy of the original property. Change this to accept a reference (or pointer), and you may have better luck. For example:
template<typename F>
void SetLink(LinkableProperty<F>* p)
{
Link = boost::bind(&LinkableProperty<F>::template Chain<F>, p, _1);
}
Should work as expected...
EDIT: Updated to show how to preserve the type across the conversion:
template <typename FT, typename TT>
TT convert(FT v)
{
return v; // default implicit conversion
}
template<>
double convert(unsigned short v)
{
std::cout << "us->d" << std::endl;
return static_cast<double>(v);
}
template<>
unsigned short convert(double v)
{
std::cout << "d->us" << std::endl;
return static_cast<unsigned short>(v);
}
static int iLCount = 1;
template <typename T>
class LinkableProperty
{
template <typename U>
struct _vref
{
typedef U vt;
_vref(vt& v) : _ref(v) {}
U& _ref;
};
public:
std::string Name;
boost::function<void(_vref<T>)> Link;
T Value;
template<typename F>
void Chain(F const& val)
{
Value = convert<typename F::vt, T>(val._ref);
std::cout << this->Name << " - " << this << ", " << &Link << ", " << val._ref << " ! " << this->Value << " - " << "\n";
if (--iLCount < 0) return;
if (!Link.empty()) Link(Value);
}
LinkableProperty() { Link = NULL; Value = T(); Name = "Level " + std::to_string(iLCount++); };
void operator =(T value) { Value = value; }
template<typename F>
void SetLink(LinkableProperty<F>* p)
{
Link = boost::bind(&LinkableProperty<F>::template Chain<_vref<T>>, p, _1);
}
void operator ()()
{
if (!Link.empty()) Link(_vref<T>(Value));
}
};
int main()
{
LinkableProperty<unsigned short> L1;
LinkableProperty<double> L2;
L2.SetLink(&L1);
L1.SetLink(&L2);
L1 = 1;
L2 = 1.1;
L1();
cout << "----------\n" << L1.Value << ", " << L2.Value << endl;
getchar();
return 0;
}
NOTE: There is some link bug which means that the updates trigger more times than necessary - you should check that...
How can I derive a class from cout so that, for example, writing to it
new_cout << "message";
would be equivalent to
cout << __FUNCTION__ << "message" << "end of message" << endl;
class Log
{
public:
Log(const std::string &funcName)
{
std::cout << funcName << ": ";
}
template <class T>
Log &operator<<(const T &v)
{
std::cout << v;
return *this;
}
~Log()
{
std::cout << " [end of message]" << std::endl;
}
};
#define MAGIC_LOG Log(__FUNCTION__)
Hence:
MAGIC_LOG << "here's a message";
MAGIC_LOG << "here's one with a number: " << 5;
#define debug_print(message) (std::cout << __FUNCTION__ << (message) << std::endl)
This has the advantage that you can disable all debug messages at once when you're done
#define debug_print(message) ()
Further from Mykola's response, I have the following implementation in my code.
The usage is
LOG_DEBUG("print 3 " << 3);
prints
DEBUG (f.cpp, 101): print 3 3
You can modify it to use FUNCTION along/in place of LINE and FILE
/// Implements a simple logging facility.
class Logger
{
std::ostringstream os_;
static Logger* instance_;
Logger();
public:
static Logger* getLogger();
bool isDebugEnabled() const;
void log(LogLevelEnum l, std::ostringstream& os, const char* filename, int lineno) const;
std::ostringstream& getStream()
{ return os_; }
};
void Logger::log(LogLevelEnum l, std::ostringstream& os, const char* filename, int lineno) const
{
std::cout << logLevelEnumToString(l) << "\t(" << fileName << ": " << lineno << ")\t- " << os.str();
os.str("");
}
#define LOG_common(level, cptext) do {\
utility::Logger::getLogger()->getStream() << cptext; \
utility::Logger::getLogger()->log(utility::level, utility::Logger::getLogger()->getStream(), __FILE__, __LINE__); \
} while(0);
enum LogLevelEnum {
DEBUG_LOG_LEVEL,
INFO_LOG_LEVEL,
WARN_LOG_LEVEL,
ERROR_LOG_LEVEL,
NOTICE_LOG_LEVEL,
FATAL_LOG_LEVEL
};
#define LOG_DEBUG(cptext) LOG_common(DEBUG_LOG_LEVEL, cptext)
#define LOG_INFO(cptext) LOG_common(INFO_LOG_LEVEL , cptext)
#define LOG_WARN(cptext) LOG_common(WARN_LOG_LEVEL , cptext)
#define LOG_ERROR(cptext) LOG_common(ERROR_LOG_LEVEL, cptext)
#define LOG_NOTICE(cptext) LOG_common(NOTICE_LOG_LEVEL, cptext)
#define LOG_FATAL(cptext) LOG_common(FATAL_LOG_LEVEL, cptext)
const char* logLevelEnumToString(LogLevelEnum m)
{
switch(m)
{
case DEBUG_LOG_LEVEL:
return "DEBUG";
case INFO_LOG_LEVEL:
return "INFO";
case WARN_LOG_LEVEL:
return "WARN";
case NOTICE_LOG_LEVEL:
return "NOTICE";
case ERROR_LOG_LEVEL:
return "ERROR";
case FATAL_LOG_LEVEL:
return "FATAL";
default:
CP_MSG_ASSERT(false, CP_TEXT("invalid value of LogLevelEnum"));
return 0;
}
}
For logging purposes I use something like
#define LOG(x) \
cout << __FUNCTION__ << x << endl
// ...
LOG("My message with number " << number << " and some more");
The problem with your approach is (as Mykola Golybyew explained) that FUNCTION is processed at compile time and would therefore always print the same name with a non-preprocessor solution.
If it's only for adding endl to your messages, you could try something like:
class MyLine {
public:
bool written;
std::ostream& stream;
MyLine(const MyLine& _line) : stream(_line.stream), written(false) { }
MyLine(std::ostream& _stream) : stream(_stream), written(false) { }
~MyLine() { if (!written) stream << "End of Message" << std::endl; }
};
template <class T> MyLine operator<<(MyLine& line, const T& _val) {
line.stream << _val;
line.written = true;
return line;
}
class MyStream {
public:
std::ostream& parentStream;
MyStream(std::ostream& _parentStream) : parentStream(_parentStream) { }
MyLine getLine() { return MyLine(parentStream); }
};
template <class T> MyLine operator<<(MyStream& stream, const T& _val) {
return (stream.getLine() << _val);
}
int main()
{
MyStream stream(std::cout);
stream << "Hello " << 13 << " some more data";
stream << "This is in the next line " << " 1 ";
return 0;
}
Note, that it's important not to return references from the operator functions. Since the MyLine should only exist as a temporary (for its destructor triggers the writing of the endl), the first object (returned by the getLine() function in MyStream) would be destructed before the second operator<< is called. Therefore the MyLine object is copied in each operator<< creating a new one. The last object gets destructed without being written to and writed the end of the message in its destructor.
Just try it out in the debugger to understand whats going on...
You have to override operator<<(), but you even don't have to subclass std::cout. You may also create a new object or use existing objects like that.
You could also override the operator. It will allow you to call another function or prefix/suffix anything that's going to leave the output buffer with whatever you wish: In your case, you'd have it output a specific string.