There is the complex<> template in C++ standard library, and it has an overloaded << operator so that it outputs complex numbers in the (real_part, im_part) format. I need to change the behavior of that operator for complex numbers so that the output format is changed to something completely different. Specifically, I need the output to be in the form real_part\tim_part. How do I do that?
There's no direct way to replace operator <<, but you do have a few options. First, you could just write your own function to print complex numbers:
template <typename T> void PrintComplex(const complex<T>& c) {
/* ... */
}
If you want to still use the nice stream syntax, then one trick you could do would be to make a wrapper class that wraps a complex and then defines its own operator << that prints it out in a different way. For example:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
complex<T> c;
};
Once you have this, you could write something like
cout << ComplexPrinter<double>(myComplex) << endl;
You can make this even cleaner by writing a function like this one to wrap the object for you:
template <typename T>
ComplexPrinter<T> wrap(const complex<T>& c) {
return ComplexPrinter<T>(c);
}
This then lets you write
cout << wrap(myComplex) << endl;
Which isn't perfect, but is pretty good.
One thing to note about the above wrapper is that it has an implicit conversion constructor set up to let you convert complex<T>s to ComplexPrinter<T>s. This means that if you have a vector< complex<T> >, you can print it out using your custom code by calling
vector< complex<double> > v = /* ... */
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " "));
On output, the implicit conversion constructor will transform your complex<double>s into the wrappers, and your custom code will do the printing for you.
If you want to be very adventurous and cast caution to the wind, you could even write the class so that it just stores a reference to the original complex, as shown here:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
const complex<T>& c;
};
This completely eliminates any copying and just makes the wrapper a thin veneer around a real complex. (No pun intended). You'd have to be very careful if you did this not to pass these objects around across scope boundaries where the original objects go out of scope, but if it's what you want it might work out just great.
Hope this helps!
template<class T>
struct my_complex_format_type {
std::complex<T> const &x;
my_complex_format_type(std::complex<T> const &x) : x (x) {}
friend std::ostream& operator<<(std::ostream &out,
my_complex_format_type const &value)
{
out << "format value.x however you like";
return out;
}
};
template<class T>
my_complex_format_type<T> my_complex_format(std::complex<T> const &x) {
return x;
}
void example() {
std::cout << my_complex_format(some_complex);
}
For any specific instantiation of complex<T>, Use a strong typedef (boost has a version) and cast to that type during << calls. Override << for that type.
If you need to override << for any variation of complex<T> then life will be harder.
My answer to the same question here: c++ display complex number with i in imaginary part produces the behavior you want, at the expense of some risk of future incompatibility because it inserts a template specialization into the std:: namespace.
There is no really tidy way to do that. My suggestion would be to just ditch iostreams and write something more C-like instead. It will probably be faster to write, faster to read and faster to execute.
Related
I have a class which acts on a list of elements, like so:
template <typename T>
class MyClass {
...
};
I need to implement certain methods, that work both on a vector<T> and a string - which is what most of the users would be using when they initialise an object as MyClass<char>().
Due to this I am being forced to follow this overloading pattern:
void method(vector<T> elements){
}
void method(string elements){
method(convertStringToVector(elements));
}
where vector<char> convertStringToVector(string str) is defined as expected.
That is, for each class method I am being forced to add an additional method that overloads for string. I find it an unnecessary overhead, and also sometimes forget to add it.
I will be doing exactly the same things on the string as I would do on the corresponding vector - same methods will be called in both cases, same iteration, etc. Thus, I was wondering if there is a cleaner way to do this, without adding much code overhead. Is there?
One possible way is to implement your method as a template, whose parameter is not restricted to be either string or vector<char>.
template <typename T>
struct MyClass
{
template <class C>
void method(C container);
};
This solves your problem because one implementation is enough for both cases:
template <typename T>
template <class C>
void MyClass<T>::method(C container)
{
std::cout << "Container has size " << container.size() << '\n';
std::cout << "First element is " << container[0] << '\n';
}
However, this will work on any container. It's not clear whether this is good (code is generic) or bad (code allows undesirable instantiations).
Imagine what happens when people try to send vector<int> instead of vector<char> to your method by mistake. Because you didn't build your code for this case, it will either display obscure compilation errors, or generate code which silently does the wrong thing at runtime.
You can create a class to use as parameter to your methods, which accepts both std::vector<char> and std::string:
class MyString
{
public:
MyString(const std::vector<char>& v) : vector(v) {}
MyString(std::vector<char>&& v) : vector(std::move(v)) {}
MyString(const std::string& s) : vector(convertStringToVector(s)) {}
std::vector<char> vector;
};
void method(MyString elements)
{
}
You can define convertStringToVector as method of your class like this:
vector<T> convertStringToVector(string str)
or a separate template function, if you need it independently for other classes.
Also I would pass the argument as reference const string &str.
If any template parameter you use is incompatible with the algorithm, the compiler will tell you about.
For those special cases you can still write a template specialization like this:
template<>
vector<SPECIALTYPE> convertStringToVector<SPECIALTYPE>(string str)
{
...
}
and implement different code for such SPECIALTYPE.
I have a class which takes an input, and sometimes I'd like to set that input by assigning a variable, and at other times I'd like the class to call a function to get its input.
In the past, I'd have just used a std::function<T()> as the input, and set a lambda to return the value of some external variable, but I'm trying to wean off an overuse of std::function. So I came up with std::variant<T, std::function<T()>>:
template <typename T>
using functionable = std::variant<T, std::function<T()>>;
// return the T or the result of the T() from the variant
template <typename T>
T get(const functionable<T>& f) {
if (f.index() == 0)
return std::get<0>(f);
else
return std::get<1>(f)();
}
Implemented thus:
class SomeClass {
private:
functionable<int> input_{0};
public:
SomeClass(const functionable<int>& input) : input_{input} {}
SomeClass& operator=(const functionable<int>& rhs) {
input_ = rhs;
return *this;
}
void print() { std::cout << get(input_) << '\n'; }
And used flexibly thus:
SomeClass foo {42}; // init with assigned value
foo.print();
foo = 101; // overwrite assigned value
foo.print();
bool a{true};
// replace input value with input lambda
foo { [this]{if(a) return 10; else return 20;} };
foo.print();
a = !a; // useful if input predicates change
foo.print();
foo = 101; // replace std::function input with assigned int
foo.print();
Is this an improvement over solely using a std::function<T()> for the input and using foo = []{return 42;} for fixed input values?
An alternative would be to make separate subclasses for assigned vs called inputs but that resulted in combinatorial explosion when there's more than one input. Are there other alternatives I'm missing?
Mathematically speaking, the constant function is just another function. And in this C++ example, there seems to be no motivating reason to treat the constant function as a special case. Performance is likely to be approximately the same, unless the large majority of your inputs are constants.
Additionally, this functionable cannot be used with std::generate, while a std::function<> wrapping a constant can. That's fixable of course by wrapping functionable in a class of its own or capturing one in another lambda. But it's just adding complexity when the simple solution will do.
I want perfect forwarding but I already know (and only accept) the type my function will take.
Here is a quick example I typed up:
class big_class
{
private:
std::string m_somethingBig;
};
class testmove
{
public:
void Add(big_class&& big)
{
std::cout << "Add via move\n";
m_bigClasses.push_back(std::move(big));
}
void Add(big_class const& big)
{
std::cout << "Add via copy\n";
m_bigClasses.push_back(big);
}
private:
std::vector<big_class> m_bigClasses;
};
int main()
{
testmove tm;
big_class big;
tm.Add(big);
tm.Add(big_class{});
}
Live Sample
Is it possible to do some form of implementation sharing between the two overloads of testmove::Add()? I want to optimize for move, and if someone does std::move() without my rvalue overload it will end up doing at least 1 copy before it is added to my vector.
Again, I realize I can solve this problem by making Add() a template function, and even using type traits and some template trickery. But I wanted to avoid this if possible. If you need to know why, I have a few reasons:
I can't do implementation hiding with a template (restrict includes and symbol visibility to a single translation unit)
Using a template here gives me more flexibility than I want (My contract requires I only use a big_class).
Using a template would impact readability/maintainability for what should be a simple interface.
The approach suggested by Xeo (take the parameter by value) is the one I would strongly recommend. However, if for some reason you can't do that (e.g., moves are expensive but less so than copies), keep reading.
I think it's possible to satisfy all your criteria, but it's only worth it if the code is complicated enough so that duplicating it would be bad. The idea is to delegate to a template that will be explicitly instantiated only for big_class.
big_class.h:
// ...
public:
void Add(big_class&& big)
{
Add_internal(std::move(big));
}
void Add(big_class const& big)
{
Add_internal(big);
}
private:
// not part of interface; defined in .cpp file
template <typename T> void Add_internal(T&& big);
big_class.cpp:
// implementation of template
template <typename T> void big_class::Add_internal(T&& big) {
// shared logic goes here
m_bigClasses.push_back(std::forward<T>(big));
}
// explicit instantiation
template void big_class::Add_internal<big_class>(big_class&&);
template void big_class::Add_internal<big_class const&>(big_class const&);
if you really can't stand the idea of adding by value, you may provide one internal templated impl:
private:
template<class X>
auto add_impl(X&& x) {
m_bigClasses.push_back(std::forward<X>(x));
}
public:
void Add(big_class&& big)
{
std::cout << "Add via move\n";
add_impl(std::move(big));
}
void Add(big_class const& big)
{
std::cout << "Add via copy\n";
add_impl(std::move(big));
}
How can this work? you're moving a const ref!
Because std::move does not move anything. It merely casts an l-value reference to an r-value reference. So const T& becomes a const T&&, which no-one ever codes for. So it will decay to match the const T& or T that people do code for.
I've been looking for this for a bit and haven't had any luck. May be that I'm searching for the wrong words, or perhaps it's an unusual request (Or simply not doable).
Regardless, my question: I want to be able to use an instance of a class... well, here's a very simple example:
class attribute
{
float value;
float min;
float max;
}
attribute attr1;
attr1.value = 5.0f;
Now, basically, I want to use attr1 as if I'm calling
attr1.value
So when I, say,
std::cout << attr1 << std::endl;
It would print 5.0 (Or just 5).
Thanks!
You need to implement
std::ostream& operator<<(std::ostream& os, attribute const& att)
{
os << att.value;
return os; // this is how you "chain" `<<`
}
Either permit att.value through public, friendship, or write a function.
Another alternative would be to build a cast operator to float:
class attribute
{
public:
operator float() const
{
return value;
}
private:
/*the rest of your class here*/
But this could introduce unexpected ambiguities.
Finally, if you want attribute to behave like a numeric type, then you can overload more operators as you see fit. For example, to overload +=, you could write
template<typename Y>
attribute& operator+=(const Y& p)
{
value += p;
return *this;
}
I often run into situations (in my C++/C++11 code), where I have a type that basically behaves like a built-in type (or a "basic simple" type like std::string), but that has a meaning
beyond a 32 bit number or a bunch of characters.
I didn't find anything useful on the Internet, because I don't really what terms to search for...
Examples:
I once worked on a system, where items were identified by an ID. And these IDs were std::strings (probably not the best idea in the first place, but that's a different story). What was really bad though was the fact, that these IDs were passed through the system as std::strings or as const char*s. So it was hard (impossible) to tell where in the
code base IDs were used when searching for the type. The variable names were all variations of ID(ID, id, Id) or key or just i or name or whatever. So you could not search by name either. So I'd prefer to pass those variables as type id_t.
Network ports: They are uint16_ts. But I would like to pass them as network_port_ts.
I generally used typedefs to make things a little nicer. This approach has multiple problems though:
You don't have to use the typedef. You can still pass variables around by the "raw" type (e.g. std::string instead of id_t).
If the raw type is a template, you are done with forward declaring the typedef (e.g. with a shared_ptr).
"Forward declaring" the typedef is a maintenance problem. If the raw type changes, you get to change stuff all over the place.
Another thing I tried with the network port example was writing a thin wrapper class sporting a operator uint16_t. This solved the problem with forward declarations. But then I ran
into a trap with some logging macros which used printf internally. The printfs still worked (well, compiled), but didn't print the port number, but (I think) the address of the object.
I figured with dimensions like weights or lengths Boost.Units might be worth a look (even so it appears a little "heavy"). But for the two examples above, it doesn't fit.
What is the best practice to achieve what I want (using Boost is an option)?
In short:
What I want to achieve is to pass "types with higher meaning" as its own type and not as the plain raw/low level/non-abstract type. (Kind of) like having a user defined type. Preferably without the huge overhead of writing a complete class for every type with basically identical implementations, only to be able to do what built-ins already can do.
1. Strong Typedefs
You can use BOOST_STRONG_TYPEDEF to get some convenience.
It does employ macros, and I think you get to do heterogeneous comparisons (e.g. id == "123").
There's two versions, be sure to take the one from Boost Utility.
2. flavoured_string<>
For strings you can cheat the system by using flavoured strings (inventor: R.Martinho Fernandes).
This leverages the fact that you can actually vary the traits on a std::basic_string, and create actually different tagged aliases:
#include <string>
#include <iostream>
namespace dessert {
template <typename Tag>
struct not_quite_the_same_traits : std::char_traits<char> {};
template <typename Tag>
using strong_string_alias = std::basic_string<char, not_quite_the_same_traits<Tag>>;
using vanilla_string = std::string;
using strawberry_string = strong_string_alias<struct strawberry>;
using caramel_string = strong_string_alias<struct caramel>;
using chocolate_string = strong_string_alias<struct chocolate>;
template <typename T>
struct special;
template <typename T>
using special_string = strong_string_alias<special<T>>;
std::ostream& operator<<(std::ostream& os, vanilla_string const& s) {
return os << "vanilla: " << s.data();
}
std::ostream& operator<<(std::ostream& os, strawberry_string const& s) {
return os << "strawberry: " << s.data();
}
std::ostream& operator<<(std::ostream& os, caramel_string const& s) {
return os << "caramel: " << s.data();
}
std::ostream& operator<<(std::ostream& os, chocolate_string const& s) {
return os << "chocolate: " << s.data();
}
template <typename T>
std::ostream& operator<<(std::ostream& os, special_string<T> const& s) {
return os << "special: " << s.data();
}
}
int main() {
dessert::vanilla_string vanilla = "foo";
dessert::strawberry_string strawberry = "foo";
dessert::caramel_string caramel = "foo";
dessert::chocolate_string chocolate = "foo";
std::cout << vanilla << '\n';
std::cout << strawberry << '\n';
std::cout << caramel << '\n';
std::cout << chocolate << '\n';
dessert::special_string<struct nuts> nuts = "foo";
std::cout << nuts << '\n';
}
To create an integer that's not an integer (or a string that's not a string) and cannot promote or demote to it), you can only create a new type, that merely means "write a new class". There is no way -at least on basic type- to inherit behaviour without aliasing. A new_type<int> has no arithmetic (unless you'll define it).
But you can define a
template<class Innertype, class Tag>
class new_type
{
Innertype m;
public:
template<class... A>
explicit new_type(A&&... a) :m(std::forward<A>(a)...) {}
const Innertype& as_native() const { return m; }
};
and do all the workout only once for all.
template<class T, class I>
auto make_new_type(I&& i)
{ return new_type<I,T>(std::forward<I>(i)); }
template<class A, class B, class T>
auto operator+(const new_type<A,T>& a, const new_type<B,T>& b)
{ return make_new_type<T>(a.as_native()+b.as_native()); }
....
and then
struct ID_tag;
typedef new_type<std::string,ID_tag> ID;
struct OtehrID_tag;
typedef new_type<std::string,OtehrID_tag> OtherID;
and ID oand OtherID cannot mix in expressions.
NOTE:
auto -function with unspecifyed return are standard from C++14, but GCC accepts it in C++11 as-well.
template <typename tag_t, typename value_t>
struct meaningful_value
{
typedef value_t value_type;
meaningful_value() : value() {}
explicit meaningful_value(const value_type & val) : value(val) {}
operator const value_type & () const { return value; }
protected:
value_type value;
};
typedef meaningful_value<struct ParamType1_tag, double> ParamType1;
typedef meaningful_value<struct ParamType2_tag, double> ParamType2;
This is basically what boost::quantity does, but allows for default construction; the tag struct can be declared inplace in the typedef, so declaring a new type of parameter is a single-line deal; you get to choose if you want a macro for it
(Edited to fix constructor name)