Loads of C++ libraries, the standard included, allow you to adapt your objects for use in the libraries. The choice is often between a member function or a free function in the same namespace.
I'd like to know mechanics and constructs the library code uses to dispatch a call which will call one of these "extension" functions, I know this decision has to take place during compile time and involves templates. The following runtime psuedocode is not possible/non-sense, the reasons are out of the scope of this question.
if Class A has member function with signature FunctionSignature
choose &A.functionSignature(...)
else if NamespaceOfClassA has free function freeFunctionSignature
choose freeFunctionSignature(...)
else
throw "no valid extension function was provided"
The code above looks like runtime code :/. So, how does the library figure out the namespace a class is in, how does it detect the three conditions, what other pitfalls are there that need to be avoided.
The motivation for my question is for me to be able to find the dispatch blocks in libraries, and to be able to use the constructs in my own code. So, detailed answers will help.
!!TO WIN BOUNTY!!
Ok so according to the answer from Steve (and the comments) ADL and SFINAE are the key constructs for wiring up the dispatch at compile time. I've got my head arround ADL (primitively) and SFINAE (again rudementary). But I don't know how they orchistrate together in the way I think they should.
I want to see a illustrative example of how these two constructs can be put together so that a library can choose at compile time whether to call a user supplied member function in an object, or a user supplied free function supplied in the same object's namespace. This should only be done using the two constructs above, no runtime dispatch of any sort.
Lets say the object in question is called NS::Car, and this object needs to provide the behaviour of MoveForward(int units), as a member function ofc. If the behaviour is to be picked up from the object's namespace it will probably look like MoveForward(const Car & car_, int units). Lets define the function that wants to dispatch mover(NS::direction d, const NS::vehicle & v_) , where direction is an enum, and v_ is a base class of NS::car.
The library doesn't do any of this at runtime, dispatch is done by the compiler when the calling code is compiled. Free functions in the same namespace as one of the arguments are found according to the rules of a mechanism called "Argument-Dependent Lookup" (ADL), sometimes called "Koenig lookup".
In cases where you have the option either to implement a free function or a member function, it may be because the library provides a template for a free function that calls the member function. Then if your object provides a function of the same name by ADL, it will be a better match than instantiating the template, and hence will be chosen first. As Space_C0wb0y says, they might use SFINAE to detect the member function in the template, and do something different according to whether it exists or not.
You can't change the behaviour of std::cout << x; by adding a member function to x, so I'm not quite sure what you mean there.
Well, I can tell you how to detect the presence of member functions of a certain name (and signature) at compile time. A friend of mine describes it here:
Detecting the Existence of Member Functions at Compile-Time
However that won't get you where you want to go, because it only works for the static type. Since you want to pass a "reference-to-vehicle", there is no way to test if the the dynamic type (the type of the concrete object behind the reference) has such a member function.
If you settle for the static type though, there is another way to do a very similar thing.
It implements "if the user provides an overloaded free function, call it, otherwise try to call the member function". And it goes like this:
namespace your_ns {
template <class T>
void your_function(T const& t)
{
the_operation(t); // unqualified call to free function
}
// in the same namespace, you provide the "default"
// for the_operation as a template, and have it call the member function:
template <class T>
void the_operation(T const& t)
{
t.the_operation();
}
} // namespace your_ns
That way the user can provide it's own overload of "the_operation",
in the same namespace as his class, so it's found by ADL. Of course
the user's "the_operation" must be "more specialized" than your default
implementation - otherwise the call would be ambiguous.
In practice that's not a problem though, since everything that restricts
the type of the parameter more than it being a reference-to-const to anything will be
"more specialized".
Example:
namespace users_ns {
class foo {};
void the_operation(foo const& f)
{
std::cout << "foo\n";
}
template <class T>
class bar {};
template <class T>
void the_operation(bar<T> const& b)
{
std::cout << "bar\n";
}
} // namespace users_ns
EDIT: after reading Steve Jessop's answer again, I realize that's basically what he wrote, only with more words :)
If you're just looking for a concrete example, consider the following:
#include <cassert>
#include <type_traits>
#include <iostream>
namespace NS
{
enum direction { forward, backward, left, right };
struct vehicle { virtual ~vehicle() { } };
struct Car : vehicle
{
void MoveForward(int units) // (1)
{
std::cout << "in NS::Car::MoveForward(int)\n";
}
};
void MoveForward(Car& car_, int units)
{
std::cout << "in NS::MoveForward(Car&, int)\n";
}
}
template<typename V>
class HasMoveForwardMember // (2)
{
template<typename U, void(U::*)(int) = &U::MoveForward>
struct sfinae_impl { };
typedef char true_t;
struct false_t { true_t f[2]; };
static V* make();
template<typename U>
static true_t check(U*, sfinae_impl<U>* = 0);
static false_t check(...);
public:
static bool const value = sizeof(check(make())) == sizeof(true_t);
};
template<typename V, bool HasMember = HasMoveForwardMember<V>::value>
struct MoveForwardDispatcher // (3)
{
static void MoveForward(V& v_, int units) { v_.MoveForward(units); }
};
template<typename V>
struct MoveForwardDispatcher<V, false> // (3)
{
static void MoveForward(V& v_, int units) { NS::MoveForward(v_, units); }
};
template<typename V>
typename std::enable_if<std::is_base_of<NS::vehicle, V>::value>::type // (4)
mover(NS::direction d, V& v_)
{
switch (d)
{
case NS::forward:
MoveForwardDispatcher<V>::MoveForward(v_, 1); // (5)
break;
case NS::backward:
// ...
break;
case NS::left:
// ...
break;
case NS::right:
// ...
break;
default:
assert(false);
}
}
struct NonVehicleWithMoveForward { void MoveForward(int) { } }; // (6)
int main()
{
NS::Car v; // (7)
//NonVehicleWithMoveForward v; // (8)
mover(NS::forward, v);
}
HasMoveForwardMember (2) is a metafunction that checks for the existence of a member function of that name with the signature void(V::*)(int) in a given class V. MoveForwardDispatcher (3) uses this information to call the member function if it exists or falls back to calling a free function if it doesn't. mover simply delegates the invocation of MoveForward to MoveForwardDispatcher (5).
The code as-posted will invoke Car::MoveForward (1), but if this member function is removed, renamed, or has its signature changed, NS::MoveForward will be called instead.
Also note that because mover is a template, a SFINAE check must be put in place to retain the semantics of only allowing objects derived from NS::vehicle to be passed in for v_ (4). To demonstrate, if one comments out (7) and uncomments (8), mover will be called with an object of type NonVehicleWithMoveForward (6), which we want to disallow despite the fact that HasMoveForwardMember<NonVehicleWithMoveForward>::value == true.
(Note: If your standard library does not come with std::enable_if and std::is_base_of, use the std::tr1:: or boost:: variants instead as available.)
The way this sort of code is usually used is to always call the free function, and implement the free function in terms of something like MoveForwardDispatcher such that the free function simply calls the passed in object's member function if it exists, without having to write overloads of that free function for every possible type that may have an appropriate member function.
Altought, sometimes, developers can used free functions or class functions, interchangeably, there are some situations, to use one another.
(1) Object / Class functions ("methods), are prefered when most of its purpouse affect only the object, or objects are inteded to compose other objects.
// object method
MyListObject.add(MyItemObject);
MyListObject.add(MyItemObject);
MyListObject.add(MyItemObject);
(2) Free ("global" or "module") functions are prefered, when involves several objects, and the objects are not part / composed of each other. Or, when the function uses plain data (structs without methods, primitive types).
MyStringNamespace.MyStringClass A = new MyStringNamespace.MyStringClass("Mercury");
MyStringNamespace.MyStringClass B = new MyStringNamespace.MyStringClass("Jupiter");
// free function
bool X = MyStringNamespace.AreEqual(A, B);
When some common module function access objects, in C++, you have the "friend keyword" that allow them to access the objects methods, without regarding scope.
class MyStringClass {
private:
// ...
protected:
// ...
// not a method, but declared, to allow access
friend:
bool AreEqual(MyStringClass A, MyStringClass B);
}
bool AreEqual(MyStringClass A, MyStringClass B) { ... }
In "almost pure object oriented" programming languages like Java or C#, where you can't have free functions, free functions are replaced with static methods, which makes stuff more complicated.
If I understood correctly your problem is simply solved using (maybe multiple) inheritance. You have somewhere a namespace free function:
namespace NS {
void DoSomething()
{
std::cout << "NS::DoSomething()" << std::endl;
}
} // namespace NS
Use a base class which forwards the same function:
struct SomethingBase
{
void DoSomething()
{
return NS::DoSomething();
}
};
If some class A deriving from SomethingBase does not implement DoSomething() calling it will call SomethingBase::DoSomething() -> NS::DoSomething():
struct A : public SomethingBase // probably other bases
{
void DoSomethingElse()
{
std::cout << "A::DoSomethingElse()" << std::endl;
}
};
If another class B deriving from SomethingBase implement DoSomething() calling it will call B::DoSomething():
struct B : public SomethingBase // probably other bases
{
void DoSomething()
{
std::cout << "B::DoSomething()" << std::endl;
}
};
So calling DoSomething() on an object deriving from SomethingBase will execute the member if existing, or the free function otherwise. Note that there is nothing to throw, you get a compile error if there is no match to your call.
int main()
{
A a;
B b;
a.DoSomething(); // "NS::DoSomething()"
b.DoSomething(); // "B::DoSomething()"
a.DoSomethingElse(); // "A::DoSomethingElse()"
b.DoSomethingElse(); // error 'DoSomethingElse' : is not a member of 'B'
}
Related
Motivation, if it helps: : I have struct member functions that are radial-basis-function kernels. They are called 1e06 x 15 x 1e05 times in a numerical simulation. Counting on devirtualization to inline virtual functions is not something I want to do for that many function calls. Also, the structs (RBF kernels) are already used as template parameters of a larger interpolation class.
Minimal working example
I have a function g() that is always the same, and I want to reuse it, so I pack it in the base class.
The function g() calls a function f() that is different in derived classes.
I don't want to use virtual functions to resolve the function names at runtime, because this incurs additional costs (I measured it in my code, it has an effect).
Here is the example:
#include <iostream>
struct A
{
double f() const { return 0; };
void g() const
{
std::cout << f() << std::endl;
}
};
struct B : private A
{
using A::g;
double f() const { return 1; };
};
struct C : private A
{
using A::g;
double f() const { return 2; };
};
int main()
{
B b;
C c;
b.g(); // Outputs 0 instead of 1
c.g(); // Outputs 0 instead of 2
}
I expected the name resolution mechanism to figure out I want to use "A::g()", but then to return to "B" or "C" to resolve the "f()" function. Something along the lines: "when I know a type at compile time, I will try to resolve all names in this type first, and do a name lookup from objects/parents something is missing, then go back to the type I was called from". However, it seems to figure out "A::g()" is used, then it sits in "A" and just picks "A::f()", even though the actual call to "g()" came from "B" and "C".
This can be solved using virtual functions, but I don't understand and would like to know the reasoning behind the name lookup sticking to the parent class when types are known at compile time.
How can I get this to work without virtual functions?
This is a standard task for the CRTP. The base class needs to know what the static type of the object is, and then it just casts itself to that.
template<typename Derived>
struct A
{
void g() const
{
cout << static_cast<Derived const*>(this)->f() << endl;
}
};
struct B : A<B>
{
using A::g;
double f() const { return 1; };
};
Also, responding to a comment you wrote, (which is maybe your real question?),
can you tell me what is the reasoning for the name lookup to stick to the base class, instead of returning to the derived class once it looked up g()?
Because classes are intended to be used for object-oriented programming, not for code reuse. The programmer of A needs to be able to understand what their code is doing, which means subclasses shouldn't be able to arbitrarily override functionality from the base class. That's what virtual is, really: A giving its subclasses permission to override that specific member. Anything that A hasn't opted-in to that for, they should be able to rely on.
Consider in your example: What if the author of B later added an integer member which happened to be called endl? Should that break A? Should B have to care about all the private member names of A? And if the author of A wants to add a member variable, should they be able to do so in a way that doesn't potentially break some subclass? (The answers are "no", "no", and "yes".)
I have a template function that I want to store a pointer to inside a std::vector.
The function looks like this:
template<typename T> void funcName(T& aT, std::vector<std::string>& fileName){...}
Now I want to store multiple pointers to functions of this kind inside a std::vector. For non-template functions I would do it like this:
typedef std::vector<std::string> string_vt;
typedef void func_t(T&, string_vt&);
typedef func_t* funcPointer;
typedef std::vector<funcPointer> funcPointer_vt;
But what is the correct syntax for template functions? How can I store them?
EDIT: First of all, thank you for your fast response. This was my first Question on Stack Overflow, so I am sorry for not providing enough information.
The set of T is finite, it can either be of type ClassA or type classB. In these function templates I want to do changes to T (so either ClassA or ClassB) with some hard coded data. I have 8 of these functions, which basically initiate a default constructed T with data specific to the function. In my program, I want to initiate 2*8 default constructed T's (8 ClassA and 8 ClassB). Therefore I run a for loop, calling one function after the other, to initiate my T objects with the function's body data.
for(int i = 0; i < initT.size(); ++i){
init_T[i]<T>(someT, fileName);
}
The for loop has as much iterations as there are function pointers inside the vector. At every iteration the function is called with some previously default constructed T and some other parameter. At the end the goal is to have 8 initiated T's with data specific to the function.
EDIT2: In case it helps, here is some actual source code. Inside the following function template I want to access my vector of function pointers in order to call the respective function.
template<typename T_Relation, typename T_Relation_Vec, bool row>
void bulk_load(initRelation_vt& aInitFunctions, T_Relation_Vec& aRel_Vec, const bool aMeasure, const uint aRuns, const char* aPath)
{
for(size_t i = 0; i < aRuns; ++i)
{
MemoryManager::freeAll();
aRel_Vec.clear();
string_vt fileNames;
for(size_t j = 0; j < aInitFunctions.size(); ++j)
{
aRel_Vec.emplace_back(T_Relation());
aInitFunctions[j]<T_Relation>(aRel_Vec[j], fileNames);
BulkLoader bl(fileNames[j].c_str(), tuples, aRel_Vec[j], delimiter, seperator);
Measure lMeasure;
if(aMeasure)
{
lMeasure.start();
}
try
{
bl.bulk_load();
if(row)
{
BulkInsertSP bi;
bi.bulk_insert(bl, aRel_Vec[j]);
}
else
{
BulkInsertPAX bi;
bi.bulk_insert(bl, aRel_Vec[j]);
}
}
catch(std::exception& ex)
{
std::cerr << "ERROR: " << ex.what() << std::endl;
}
lMeasure.stop();
if(aMeasure)
{
std::ofstream file;
file.open (aPath, std::ios::out | std::ios::app);
//print_result(file, flag, lMeasure.mTotalTime());
file.close();
}
}
}
}
This line is where the vector of function template pointers is accessed.
aInitFunctions[j]<T_Relation>(aRel_Vec[j], fileNames);
Templates are an advanced technique for static polymorphism. In a typed language, like C++, without static polymorphism you would have to separately define every entity used and precisely indicate every entity referred to.
Mechanisms of static polymorphism in C++ allow to automate indication of function or method and defer it until build via overloading. It allows you to define multiple entities sharing some characteristics at once via templates and defer definition of particular specializations until build, inferred from use.
(Notice that in various scenarios, static polymorphism allows separate code, so that changes to use and to definition are independent, which is very useful.)
The important implication of this mechanism is that every specialization of your template may be of different type. It is unclear, as of when I'm responding, whether you want to store pointers to a single or multiple types of specialization in one type of container. The possibilities depend also on parameter and result types of the function template.
A function in C++ has a type that is a combination of list of its parameter types and its return type. In other words, two functions that take and return the same types are of the same type. If your function template neither took or returned template parameter type (ie. T) nor templated type (eg. std::vector<T>), every specialization of this function template would be taking and returning the same types and would therefore be a function of the same type.
template <typename T>
int func() { ... }
This (arguably useless) function template takes no arguments and returns int, whatever T is used to specialize the template. Therefore a pointer to it could be used wherever the parameter is defined as int (*f)(). In this case you could keep pointer to any specialization in one vector.
typedef std::vector<std::string> string_vt;
typedef int func_t();
typedef func_t* funcPointer;
typedef std::vector<funcPointer> funcPointer_vt;
funcPointer x = &func<int>;
funcPointer y = &func<float>;
As can be seen, every specialization of your function template is of the same type and both pointers fit in the same container.
Next case - what if function header depends on a template parameter? Every specialization would have a different signature, that is a different function type. The pointers to all of them would be of different types - so it wouldn't be possible to even typedef this pointer once.
template <typename T>
void func(std::vector<T> param) { ... }
In this case function template specialization is of different type depending on T used to specialize.
typedef int func_t_int(std::vector<int>);
typedef func_t_int* funcPointerInt;
typedef std::vector<funcPointerInt> funcPointerInt_vt;
typedef float func_t_float(std::vector<float>);
typedef func_t_float* funcPointerFloat;
typedef std::vector<funcPointerFloat> funcPointerFloat_vt;
funcPointerInt x = &func<int>;
funcPointerFloat x = &func<float>;
Specializations are of different types, because they take different type of vectors. Pointers do not fit in the same container.
It's mention-worthy at this point, that in this case it's not necessary to define every pointer type separately. They could be a template type:
template <typename T>
using funcPointer = void (*)(std::vector<T>);
Which now allows funcPointer<int> to be used as a type qualifier, in place of earlier funcPointerInt.
funcPointer<float> y = &func<float>;
In more complicated situations a template could be created, whose every specialization is of a different type, and then would use a single instance of concrete vector to store various pointers to functions of type of only one of the specializations of your template. Although a simple template like in the example can only produce a single function per type, because every specialization yields one type of function and one function of that type, it's not impossible to conceive a scenario where various pointers to functions are obtained, both to specializations and usual functions, perhaps from various sources. So the technique could be useful.
But yet another scenario is that despite every specialization of the template being of different type, there's a need to store pointers to various specializations in single std::vector. In this case dynamic polymorphism will be helpful. To store values of different types, fe. pointers to functions of different types, in one type of variable, requires inheritance. It is possible to store any subclass in a field defined as superclass. Note however, that this is unlikely to accomplish anything really and probably not what you're really looking for.
I see two general possibilities now. Either use a class template with a method, which inherits from a non-template class.
template <typename T>
class MyClass : BaseClass
{
public:
T operator()(const T& param, int value);
}
MyClass<int> a;
MyClass<float> b;
BaseClass* ptr = &a;
ptr = &b;
While every specialization of this class may be of a different type, they all share superclass BaseClass, so a pointer to a BaseClass can actually point to any of them, and a std::vector<funcPointerBase> can be used to store them. By overloading operator() we have create an object that mimics a function. The interesting property of such a class is that it can have multiple instances created with parameter constructors. So effectively class template produces specializations of multiple types, and in turn every specialized class can produce instances of varying parametrization.
template <typename T>
class MyClass : BaseClass
{
int functor_param;
public:
MyClass(int functor_param);
T operator()(const T& param, int value);
}
This version allows creation of instances that work differently:
MyClass<int> a(1);
MyClass<int> b(2);
MyClass<float> c(4);
MyClass<int>* ptr = &a;
ptr = &b;
ptr = &c;
I am no expert on functors, just wanted to present the general idea. If it seems interesting, I suggest researching it now.
But technically we're not storing function pointers, just regular object pointers. Well, as stated before, we need inheritance to use one type of variable to store values of various types. So if we're not using inheritance to exchange our procedural functions for something dynamically polymorphic, we must do the same to pointers.
template <typename T>
T func(std::pair < T, char>) {}
template <typename T>
using funcPointer = T(*)(std::pair<T, char>);
template <typename T>
class MyPointer : BasePointer
{
funcPointer<T> ptr;
public:
MyPointer(funcPointer<T> ptr);
T()(std::pair <T, char>) operator*(std::pair <T, char> pair)
{
*ptr(pair);
}
};
This, again, allows creation of single std::vector<BasePointer> to store all possible pseudo-function-pointers.
Now the very important bit. How would You go about calling those, in either scenario? Since in both cases they are stored in a single std::vector<>, they are treated as if they were of the base type. A specific function call needs parameters of specific type and returns a specific type. If there was anything that all subclasses can do in the same way, it could be exposed by defining such a method in base class (in either scenario using functors or pointer..ors?), but a specific specialized function call is not that kind of thing. Every function call that You would want to perform in the end, after all this struggle, would be of a different type, requiring different type of parameters and/or returning different type of value. So they could never all fit into the same place in usual, not templated code, the same circumstances in execution. If they did, then dynamic polymorphism wouldn't be necessary to solve this problem in the first place.
One thing that could be done - which is greatly discouraged and probably defeats the purpose of dynamic polymorphism - is to detect subclass type at runtime and proceed accordingly. Research that, if you're convinced you have a good case for using this. Most likely though, it's probably a big anti-pattern.
But technically, anything you may want to do is possible somehow.
If I have correctly understood you, I may have a really simple and efficient solution:
template<class...Ts>
struct functor{
//something like a dynamic vtable
std::tuple<void(*)(Ts&,std::vector<std::string>&)...> instantiated_func_ptr;
template<class T>
void operator ()(T& aT,std::vector<std::string>& fileName){
get<void(*)(T&,std::vector<std::string>&)>(instantiated_func_ptr)
(aT,fileName);
}
};
Voilà!!
Until c++17, get<typename> is not defined so we have to define it (before the definition of the template functor above):
template<class T,class...Ts>
struct find_type{
//always fail if instantiated
static_assert(sizeof...(Ts)==0,"type not found");
};
template<class T,class U,class...Ts>
struct find_type<T,U,Ts...>:std::integral_constant<size_t,
find_type<T,Ts...>::value+1>{};
template<class T,class...Ts>
struct find_type<T,T,Ts...>:std::integral_constant<size_t,0>{};
template<class T,class...Ts>
constexpr decltype(auto) get(const std::tuple<Ts...>& t){
return get<find_type<T,Ts...>::value>(t);
}
And an example to show how to use it:
struct A{
void show() const{
std::cout << "A" << "\n";
}
};
struct B{
void show() const{
std::cout << "B" << "\n";
}
};
template<class T>
void func1(T& aT,std::vector<std::string>& fileName){
std::cout << "func1: ";
aT.show();
}
template<class T>
void func2(T& aT,std::vector<std::string>& fileName){
std::cout << "func2: ";
aT.show();
}
template<class T>
void func3(T& aT,std::vector<std::string>& fileName){
std::cout << "func3: ";
aT.show();
}
using functorAB = functor<A,B>;
int main(){
auto functor1=functorAB{{func1,func1}};//equivalent to functorAB{{func1<A>,func1<B>}}
auto functor2=functorAB{{func2,func2}};
auto functor3=functorAB{{func3,func3}};
auto v=std::vector<functorAB>{functor1,functor2,functor3};
auto a=A{};
auto b=B{};
auto fileNames = std::vector<std::string>{"file1","file2"};
for(auto& tf:v)
tf(a,fileNames);
for(auto& tf:v)
tf(b,fileNames);
}
In practice it is just a reproduction of the virtual call mechanism,
the tuple in functor is kind of virtual table. This code is not
more efficient than if you had written an abstract functor with virtual
operator() for each of your class A and B and then implemented it for each of
your functions... but it is much more concise, easier to maintain and may produce less binary code.
I need to store multiple types of a template class in a single vector.
Eg, for:
template <typename T>
class templateClass{
bool someFunction();
};
I need one vector that will store all of:
templateClass<int> t1;
templateClass<char> t2;
templateClass<std::string> t3;
etc
As far as I know this is not possible, if it is could someone say how?
If it isn't possible could someone explain how to make the following work?
As a work around I tried to use a base, non template class and inherit the template class from it.
class templateInterface{
virtual bool someFunction() = 0;
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction();
};
I then created a vector to store the base "templateInterface" class:
std::vector<templateInterface> v;
templateClass<int> t;
v.push_back(t);
This produced the following error:
error: cannot allocate an object of abstract type 'templateInterface'
note: because the following virtual functions are pure within 'templateInterface'
note: virtual bool templateInterface::someFunction()
To fix this error I made the function in templateInterface not a pure virtual by providing a function body, this compiled but when calling the function the overide is not used, but instead the body in the virtual function.
Eg:
class templateInterface{
virtual bool someFunction() {return true;}
};
template <typename T>
class templateClass : public templateInterface{
bool someFunction() {return false;}
};
std::vector<templateInterface> v;
templateClass<int> i;
v.push_back(i);
v[0].someFunction(); //This returns true, and does not use the code in the 'templateClass' function body
Is there any way to fix this so that the overridden function is used, or is there another workaround to store multiple template types in a single vector?
Why your code doesn't work:
Calling a virtual function on a value doesn't use polymorphism. It calls the function which is defined for the type of this exact symbol as seen by the compiler, not the runtime type. When you insert sub types into a vector of the base type, your values will be converted into the base type ("type slicing"), which is not what you want. Calling functions on them will now call the function as defined for the base type, since not it is of that type.
How to fix this?
The same problem can be reproduced with this code snippet:
templateInterface x = templateClass<int>(); // Type slicing takes place!
x.someFunction(); // -> templateInterface::someFunction() is called!
Polymorphism only works on a pointer or reference type. It will then use the runtime type of the object behind the pointer / reference to decide which implementation to call (by using it's vtable).
Converting pointers is totally "safe" with regard to type slicing. Your actual values won't be converted at all and polymorphism will work as expected.
Example, analogous to the code snippet above:
templateInterface *x = new templateClass<int>(); // No type slicing takes place
x->someFunction(); // -> templateClass<int>::someFunction() is called!
delete x; // Don't forget to destroy your objects.
What about vectors?
So you have to adopt these changes in your code. You can simply store pointers to actual types in the vector, instead of storing the values directly.
When working with pointers you also have to care about deleting your allocated objects. For this you can use smart pointers which care about deletion automatically. unique_ptr is one such smart pointer type. It deletes the pointee whenever it goes out of scope ("unique ownership" - the scope being the owner). Assuming the lifetime of your objects is bound to the scope this is what you should use:
std::vector<std::unique_ptr<templateInterface>> v;
templateClass<int> *i = new templateClass<int>(); // create new object
v.push_back(std::unique_ptr<templateInterface>(i)); // put it in the vector
v.emplace_back(new templateClass<int>()); // "direct" alternative
Then, call a virtual function on one of these elements with the following syntax:
v[0]->someFunction();
Make sure you make all functions virtual which should be possible to be overridden by subclasses. Otherwise their overridden version will not be called. But since you already introduced an "interface", I'm sure you are working with abstract functions.
Alternative approaches:
Alternative ways to do what you want is to use a variant type in the vector. There are some implementations of variant types, the Boost.Variant being a very popular one. This approach is especially nice if you don't have a type hierarchy (for example when you store primitive types). You would then use a vector type like std::vector<boost::variant<int, char, bool>>
Polymorphism only works through pointers or references. You'll
need the non-template base. Beyond that, you'll need to decide
where the actual objects in container will live. If they're all
static objects (with sufficient lifetime), just using
a std::vector<TemplateInterface*>, and inserting with
v.push_back(&t1);, etc., should do the trick. Otherwise,
you'll probably want to support cloning, and keep clones in the
vector: preferably with Boost pointer containers, but
std::shared_ptr can be used as well.
The solutions given so far are fine though be aware that in case you were returning the template type other than bool in your example , none of these would help as the vtable slots would not be able to be measured before hand. There are actually limits , from a design point of view , for using a template oriented polymorphic solution.
Solution nr. 1
This solution inspired by Sean Parent's C++ Seasoning talk. I highly recommend to check it out on youtube. My solution simplified a bit and the key is to store object in method itself.
One method only
Create a class that will invoke method of stored object.
struct object {
template <class T>
object(T t)
: someFunction([t = std::move(t)]() { return t.someFunction(); })
{ }
std::function<bool()> someFunction;
};
Then use it like this
std::vector<object> v;
// Add classes that has 'bool someFunction()' method
v.emplace_back(someClass());
v.emplace_back(someOtherClass());
// Test our vector
for (auto& x : v)
std::cout << x.someFunction() << std::endl;
Several methods
For several methods use shared pointer to share object between methods
struct object {
template <class T>
object(T&& t) {
auto ptr = std::make_shared<std::remove_reference_t<T>>(std::forward<T>(t));
someFunction = [ptr]() { return ptr->someFunction(); };
someOtherFunction = [ptr](int x) { ptr->someOtherFunction(x); };
}
std::function<bool()> someFunction;
std::function<void(int)> someOtherFunction;
};
Other types
Primitive types (such as int, float, const char*) or classes (std::string etc.) may be wrapped in the same way as object class do but behave differently. For example:
struct otherType {
template <class T>
otherType(T t)
: someFunction([t = std::move(t)]() {
// Return something different
return true;
})
{ }
std::function<bool()> someFunction;
};
So now it is possible to add types that does not have someFunction method.
v.emplace_back(otherType(17)); // Adding an int
v.emplace_back(otherType("test")); // A string
Solution nr. 2
After some thoughts what we basically done in first solution is created array of callable functions. So why not just do the following instead.
// Example class with method we want to put in array
struct myclass {
void draw() const {
std::cout << "myclass" << std::endl;
}
};
// All other type's behaviour
template <class T>
void draw(const T& x) {
std::cout << typeid(T).name() << ": " << x << std::endl;
}
int main()
{
myclass x;
int y = 17;
std::vector<std::function<void()>> v;
v.emplace_back(std::bind(&myclass::draw, &x));
v.emplace_back(std::bind(draw<int>, y));
for (auto& fn : v)
fn();
}
Conclusion
Solution nr. 1 is definitely an interesting method that does not require inheritance nor virtual functions. And can be used to other stuff where you need to store a template argument to be used later.
Solution nr. 2, on the other hand, is simpler, more flexible and probably a better choice here.
If you're looking at a container to store multiple types, then you should explore boost variant from the popular boost library.
From the wikipedia article about Lambda functions and expressions:
users will often wish to define predicate functions near the place
where they make the algorithm function call. The language has only one
mechanism for this: the ability to define a class inside of a
function. ... classes defined in functions do not permit them to be used in templates
Does this mean that use of nested structure inside function is silently deprecated after C++0x lambda are in place ?
Additionally, what is the meaning of last line in above paragraph ? I know that nested classes cannot be template; but that line doesn't mean that.
I'm not sure I understand your confusion, but I'll just state all the facts and let you sort it out. :)
In C++03, this was legal:
#include <iostream>
int main()
{
struct func
{
void operator()(int x) const
{
std::cout << x << std::endl;
}
};
func f; // okay
f(-1); // okay
for (std::size_t i = 0; i < 10; ++i)
f(i) ; // okay
}
But if we tried doing this, it wasn't:
template <typename Func>
void exec(Func f)
{
f(1337);
}
int main()
{
// ...
exec(func); // not okay, local classes not usable as template argument
}
That left us with an issue: we want to define predicates to use for this function, but we can't put it in the function. So we had to move it to whatever outer scope there was and use it there. Not only did that clutters that scope with stuff nobody else needed to know about, but it moved the predicate away from where it's used, making it tougher to read the code.
It could still be useful, for the occasional reused chunk of code within the function (for example, in the loop above; you could have the function predicate to some complex thing with its argument), but most of the time we wanted to use them in templates.
C++0x changes the rules to allow the above code to work. They additionally added lambdas: syntax for creating function objects as expressions, like so:
int main()
{
// same function as above, more succinct
auto func = [](int x){ std::cout << x << std::endl; };
// ...
}
This is exactly like above, but simpler. So do we still have any use for "real" local classes? Sure. Lambda's fall short of full functionality, after all:
#include <iostream>
template <typename Func>
void exec(Func func)
{
func(1337);
}
int main()
{
struct func
{
// note: not possible in C++0x lambdas
void operator()(const char* str) const
{
std::cout << str << std::endl;
}
void operator()(int val) const
{
std::cout << val << std::endl;
}
};
func f; // okay
f("a string, ints next"); // okay
for (std::size_t i = 0; i < 10; ++i)
f(i) ; // okay
exec(f); // okay
}
That said, with lambda's you probably won't see local classes any more than before, but for completely different reasons: one is nearly useless, the other is nearly superseded.
Is there any use case for class inside function after introduction of lambda ?
Definitely. Having a class inside a function is about:
localising it as a private implementation detail of the code intending to use it,
preventing other code using and becoming dependent on it,
being independent of the outer namespace.
Obviously there's a threshold where having a large class inside a function harms readability and obfuscates the flow of the function itself - for most developers and situations, that threshold is very low. With a large class, even though only one function is intended to use it, it may be cleaner to put both into a separate source file. But, it's all just tuning to taste.
You can think of this as the inverse of having private functions in a class: in that situation, the outer API is the class's public interface, with the function kept private. In this situation, the function is using a class as a private implementation detail, and the latter is also kept private. C++ is a multi-paradigm language, and appropriately gives such flexibility in modelling the hierarchy of program organisation and API exposure.
Examples:
a function deals with some external data (think file, network, shared memory...) and wishes to use a class to represent the binary data layout during I/O; it may decide to make that class local if it only has a few fields and is of no use to other functions
a function wants to group a few items and allocate an array of them in support of the internal calculations it does to derive its return value; it may create a simple struct to wrap them up.
a class is given a nasty bitwise enum, or perhaps wants to reinterpret a float or double for access to the mantisa/exponent/sign, and decides internally to model the value using a struct with suitable-width bitfields for convenience (note: implementation defined behaviours)
classes defined in functions do not permit them to be used in templates
I think you commented that someone else's answer had explained this, but anyway...
void f()
{
struct X { };
std::vector<X> xs; // NOPE, X is local
}
Defining structures inside functions was never a particularly good way to deal with the lack of predicates. It works if you have a virtual base, but it's still a pretty ugly way to deal with things. It might look a bit like this:
struct virtual_base {
virtual void operator()() = 0;
};
void foo() {
struct impl : public virtual_base {
void operator()() { /* ... */ }
};
register_callback(new impl);
}
You can still continue to use these classes-inside-functions if you want of course - they're not deprecated or crippled; they were simply restricted from the very start. For example, this code is illegal in versions of C++ prior to C++0x:
void foo() {
struct x { /* ... */ };
std::vector<x> y; // illegal; x is a class defined in a function
boost::function<void()> z = x(); // illegal; x is used to instantiate a templated constructor of boost::function
}
This kind of usage was actually made legal in C++0x, so if anything the usefulness of inner classes has actually be expanded. It's still not really a nice way of doing things most of the time though.
Boost.Variant.
Lambdas don't work with variants, as variants need objects that have more than one operator() (or that have a templated operator()). C++0x allows local classes to be used in templates now, so boost::apply_variant can take them.
As Tony mentioned, a class inside a function is not only about predicates. Besides other use cases, it allows to create a factory function that creates objects confirming to an interface without exposing the implementing class. See this example:
#include <iostream>
/* I think i found this "trick" in [Alexandrescu, Modern C++ Design] */
class MyInterface {
public:
virtual void doSomethingUseful() = 0;
};
MyInterface* factory() {
class HiddenImplementation : public MyInterface {
void doSomethingUseful () {
std::cout << "Hello, World!" << std::endl;
}
};
return new HiddenImplementation();
}
int main () {
auto someInstance = factory();
someInstance->doSomethingUseful();
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
No C++ love when it comes to the "hidden features of" line of questions? Figured I would throw it out there. What are some of the hidden features of C++?
Most C++ programmers are familiar with the ternary operator:
x = (y < 0) ? 10 : 20;
However, they don't realize that it can be used as an lvalue:
(a == 0 ? a : b) = 1;
which is shorthand for
if (a == 0)
a = 1;
else
b = 1;
Use with caution :-)
You can put URIs into C++ source without error. For example:
void foo() {
http://stackoverflow.com/
int bar = 4;
...
}
Pointer arithmetics.
C++ programmers prefer to avoid pointers because of the bugs that can be introduced.
The coolest C++ I've ever seen though? Analog literals.
I agree with most posts there: C++ is a multi-paradigm language, so the "hidden" features you'll find (other than "undefined behaviours" that you should avoid at all cost) are clever uses of facilities.
Most of those facilities are not build-in features of the language, but library-based ones.
The most important is the RAII, often ignored for years by C++ developers coming from the C world. Operator overloading is often a misunderstood feature that enable both array-like behaviour (subscript operator), pointer like operations (smart pointers) and build-in-like operations (multiplying matrices.
The use of exception is often difficult, but with some work, can produce really robust code through exception safety specifications (including code that won't fail, or that will have a commit-like features that is that will succeed, or revert back to its original state).
The most famous of "hidden" feature of C++ is template metaprogramming, as it enables you to have your program partially (or totally) executed at compile-time instead of runtime. This is difficult, though, and you must have a solid grasp on templates before trying it.
Other make uses of the multiple paradigm to produce "ways of programming" outside of C++'s ancestor, that is, C.
By using functors, you can simulate functions, with the additional type-safety and being stateful. Using the command pattern, you can delay code execution. Most other design patterns can be easily and efficiently implemented in C++ to produce alternative coding styles not supposed to be inside the list of "official C++ paradigms".
By using templates, you can produce code that will work on most types, including not the one you thought at first. You can increase type safety,too (like an automated typesafe malloc/realloc/free). C++ object features are really powerful (and thus, dangerous if used carelessly), but even the dynamic polymorphism have its static version in C++: the CRTP.
I have found that most "Effective C++"-type books from Scott Meyers or "Exceptional C++"-type books from Herb Sutter to be both easy to read, and quite treasures of info on known and less known features of C++.
Among my preferred is one that should make the hair of any Java programmer rise from horror: In C++, the most object-oriented way to add a feature to an object is through a non-member non-friend function, instead of a member-function (i.e. class method), because:
In C++, a class' interface is both its member-functions and the non-member functions in the same namespace
non-friend non-member functions have no privileged access to the class internal. As such, using a member function over a non-member non-friend one will weaken the class' encapsulation.
This never fails to surprise even experienced developers.
(Source: Among others, Herb Sutter's online Guru of the Week #84: http://www.gotw.ca/gotw/084.htm )
One language feature that I consider to be somewhat hidden, because I had never heard about it throughout my entire time in school, is the namespace alias. It wasn't brought to my attention until I ran into examples of it in the boost documentation. Of course, now that I know about it you can find it in any standard C++ reference.
namespace fs = boost::filesystem;
fs::path myPath( strPath, fs::native );
Not only can variables be declared in the init part of a for loop, but also classes and functions.
for(struct { int a; float b; } loop = { 1, 2 }; ...; ...) {
...
}
That allows for multiple variables of differing types.
The array operator is associative.
A[8] is a synonym for *(A + 8). Since addition is associative, that can be rewritten as *(8 + A), which is a synonym for..... 8[A]
You didn't say useful... :-)
One thing that's little known is that unions can be templates too:
template<typename From, typename To>
union union_cast {
From from;
To to;
union_cast(From from)
:from(from) { }
To getTo() const { return to; }
};
And they can have constructors and member functions too. Just nothing that has to do with inheritance (including virtual functions).
C++ is a standard, there shouldn't be any hidden features...
C++ is a multi-paradigm language, you can bet your last money on there being hidden features. One example out of many: template metaprogramming. Nobody in the standards committee intended there to be a Turing-complete sublanguage that gets executed at compile-time.
Another hidden feature that doesn't work in C is the functionality of the unary + operator. You can use it to promote and decay all sorts of things
Converting an Enumeration to an integer
+AnEnumeratorValue
And your enumerator value that previously had its enumeration type now has the perfect integer type that can fit its value. Manually, you would hardly know that type! This is needed for example when you want to implement an overloaded operator for your enumeration.
Get the value out of a variable
You have to use a class that uses an in-class static initializer without an out of class definition, but sometimes it fails to link? The operator may help to create a temporary without making assumptins or dependencies on its type
struct Foo {
static int const value = 42;
};
// This does something interesting...
template<typename T>
void f(T const&);
int main() {
// fails to link - tries to get the address of "Foo::value"!
f(Foo::value);
// works - pass a temporary value
f(+Foo::value);
}
Decay an array to a pointer
Do you want to pass two pointers to a function, but it just won't work? The operator may help
// This does something interesting...
template<typename T>
void f(T const& a, T const& b);
int main() {
int a[2];
int b[3];
f(a, b); // won't work! different values for "T"!
f(+a, +b); // works! T is "int*" both time
}
Lifetime of temporaries bound to const references is one that few people know about. Or at least it's my favorite piece of C++ knowledge that most people don't know about.
const MyClass& x = MyClass(); // temporary exists as long as x is in scope
A nice feature that isn't used often is the function-wide try-catch block:
int Function()
try
{
// do something here
return 42;
}
catch(...)
{
return -1;
}
Main usage would be to translate exception to other exception class and rethrow, or to translate between exceptions and return-based error code handling.
Many know of the identity / id metafunction, but there is a nice usecase for it for non-template cases: Ease writing declarations:
// void (*f)(); // same
id<void()>::type *f;
// void (*f(void(*p)()))(int); // same
id<void(int)>::type *f(id<void()>::type *p);
// int (*p)[2] = new int[10][2]; // same
id<int[2]>::type *p = new int[10][2];
// void (C::*p)(int) = 0; // same
id<void(int)>::type C::*p = 0;
It helps decrypting C++ declarations greatly!
// boost::identity is pretty much the same
template<typename T>
struct id { typedef T type; };
A quite hidden feature is that you can define variables within an if condition, and its scope will span only over the if, and its else blocks:
if(int * p = getPointer()) {
// do something
}
Some macros use that, for example to provide some "locked" scope like this:
struct MutexLocker {
MutexLocker(Mutex&);
~MutexLocker();
operator bool() const { return false; }
private:
Mutex &m;
};
#define locked(mutex) if(MutexLocker const& lock = MutexLocker(mutex)) {} else
void someCriticalPath() {
locked(myLocker) { /* ... */ }
}
Also BOOST_FOREACH uses it under the hood. To complete this, it's not only possible in an if, but also in a switch:
switch(int value = getIt()) {
// ...
}
and in a while loop:
while(SomeThing t = getSomeThing()) {
// ...
}
(and also in a for condition). But i'm not too sure whether these are all that useful :)
Preventing comma operator from calling operator overloads
Sometimes you make valid use of the comma operator, but you want to ensure that no user defined comma operator gets into the way, because for instance you rely on sequence points between the left and right side or want to make sure nothing interferes with the desired action. This is where void() comes into game:
for(T i, j; can_continue(i, j); ++i, void(), ++j)
do_code(i, j);
Ignore the place holders i put for the condition and code. What's important is the void(), which makes the compiler force to use the builtin comma operator. This can be useful when implementing traits classes, sometimes, too.
Array initialization in constructor.
For example in a class if we have a array of int as:
class clName
{
clName();
int a[10];
};
We can initialize all elements in the array to its default (here all elements of array to zero) in the constructor as:
clName::clName() : a()
{
}
Oooh, I can come up with a list of pet hates instead:
Destructors need to be virtual if you intend use polymorphically
Sometimes members are initialized by default, sometimes they aren't
Local clases can't be used as template parameters (makes them less useful)
exception specifiers: look useful, but aren't
function overloads hide base class functions with different signatures.
no useful standardisation on internationalisation (portable standard wide charset, anyone? We'll have to wait until C++0x)
On the plus side
hidden feature: function try blocks. Unfortunately I haven't found a use for it. Yes I know why they added it, but you have to rethrow in a constructor which makes it pointless.
It's worth looking carefully at the STL guarantees about iterator validity after container modification, which can let you make some slightly nicer loops.
Boost - it's hardly a secret but it's worth using.
Return value optimisation (not obvious, but it's specifically allowed by the standard)
Functors aka function objects aka operator(). This is used extensively by the STL. not really a secret, but is a nifty side effect of operator overloading and templates.
You can access protected data and function members of any class, without undefined behavior, and with expected semantics. Read on to see how. Read also the defect report about this.
Normally, C++ forbids you to access non-static protected members of a class's object, even if that class is your base class
struct A {
protected:
int a;
};
struct B : A {
// error: can't access protected member
static int get(A &x) { return x.a; }
};
struct C : A { };
That's forbidden: You and the compiler don't know what the reference actually points at. It could be a C object, in which case class B has no business and clue about its data. Such access is only granted if x is a reference to a derived class or one derived from it. And it could allow arbitrary piece of code to read any protected member by just making up a "throw-away" class that reads out members, for example of std::stack:
void f(std::stack<int> &s) {
// now, let's decide to mess with that stack!
struct pillager : std::stack<int> {
static std::deque<int> &get(std::stack<int> &s) {
// error: stack<int>::c is protected
return s.c;
}
};
// haha, now let's inspect the stack's middle elements!
std::deque<int> &d = pillager::get(s);
}
Surely, as you see this would cause way too much damage. But now, member pointers allow circumventing this protection! The key point is that the type of a member pointer is bound to the class that actually contains said member - not to the class that you specified when taking the address. This allows us to circumvent checking
struct A {
protected:
int a;
};
struct B : A {
// valid: *can* access protected member
static int get(A &x) { return x.*(&B::a); }
};
struct C : A { };
And of course, it also works with the std::stack example.
void f(std::stack<int> &s) {
// now, let's decide to mess with that stack!
struct pillager : std::stack<int> {
static std::deque<int> &get(std::stack<int> &s) {
return s.*(pillager::c);
}
};
// haha, now let's inspect the stack's middle elements!
std::deque<int> &d = pillager::get(s);
}
That's going to be even easier with a using declaration in the derived class, which makes the member name public and refers to the member of the base class.
void f(std::stack<int> &s) {
// now, let's decide to mess with that stack!
struct pillager : std::stack<int> {
using std::stack<int>::c;
};
// haha, now let's inspect the stack's middle elements!
std::deque<int> &d = s.*(&pillager::c);
}
Another hidden feature is that you can call class objects that can be converted to function pointers or references. Overload resolution is done on the result of them, and arguments are perfectly forwarded.
template<typename Func1, typename Func2>
class callable {
Func1 *m_f1;
Func2 *m_f2;
public:
callable(Func1 *f1, Func2 *f2):m_f1(f1), m_f2(f2) { }
operator Func1*() { return m_f1; }
operator Func2*() { return m_f2; }
};
void foo(int i) { std::cout << "foo: " << i << std::endl; }
void bar(long il) { std::cout << "bar: " << il << std::endl; }
int main() {
callable<void(int), void(long)> c(foo, bar);
c(42); // calls foo
c(42L); // calls bar
}
These are called "surrogate call functions".
Hidden features:
Pure virtual functions can have implementation. Common example, pure virtual destructor.
If a function throws an exception not listed in its exception specifications, but the function has std::bad_exception in its exception specification, the exception is converted into std::bad_exception and thrown automatically. That way you will at least know that a bad_exception was thrown. Read more here.
function try blocks
The template keyword in disambiguating typedefs in a class template. If the name of a member template specialization appears after a ., ->, or :: operator, and that name has explicitly qualified template parameters, prefix the member template name with the keyword template. Read more here.
function parameter defaults can be changed at runtime. Read more here.
A[i] works as good as i[A]
Temporary instances of a class can be modified! A non-const member function can be invoked on a temporary object. For example:
struct Bar {
void modify() {}
}
int main (void) {
Bar().modify(); /* non-const function invoked on a temporary. */
}
Read more here.
If two different types are present before and after the : in the ternary (?:) operator expression, then the resulting type of the expression is the one that is the most general of the two. For example:
void foo (int) {}
void foo (double) {}
struct X {
X (double d = 0.0) {}
};
void foo (X) {}
int main(void) {
int i = 1;
foo(i ? 0 : 0.0); // calls foo(double)
X x;
foo(i ? 0.0 : x); // calls foo(X)
}
map::operator[] creates entry if key is missing and returns reference to default-constructed entry value. So you can write:
map<int, string> m;
string& s = m[42]; // no need for map::find()
if (s.empty()) { // assuming we never store empty values in m
s.assign(...);
}
cout << s;
I'm amazed at how many C++ programmers don't know this.
Putting functions or variables in a nameless namespace deprecates the use of static to restrict them to file scope.
Defining ordinary friend functions in class templates needs special attention:
template <typename T>
class Creator {
friend void appear() { // a new function ::appear(), but it doesn't
… // exist until Creator is instantiated
}
};
Creator<void> miracle; // ::appear() is created at this point
Creator<double> oops; // ERROR: ::appear() is created a second time!
In this example, two different instantiations create two identical definitions—a direct violation of the ODR
We must therefore make sure the template parameters of the class template appear in the type of any friend function defined in that template (unless we want to prevent more than one instantiation of a class template in a particular file, but this is rather unlikely). Let's apply this to a variation of our previous example:
template <typename T>
class Creator {
friend void feed(Creator<T>*){ // every T generates a different
… // function ::feed()
}
};
Creator<void> one; // generates ::feed(Creator<void>*)
Creator<double> two; // generates ::feed(Creator<double>*)
Disclaimer: I have pasted this section from C++ Templates: The Complete Guide / Section 8.4
void functions can return void values
Little known, but the following code is fine
void f() { }
void g() { return f(); }
Aswell as the following weird looking one
void f() { return (void)"i'm discarded"; }
Knowing about this, you can take advantage in some areas. One example: void functions can't return a value but you can also not just return nothing, because they may be instantiated with non-void. Instead of storing the value into a local variable, which will cause an error for void, just return a value directly
template<typename T>
struct sample {
// assume f<T> may return void
T dosomething() { return f<T>(); }
// better than T t = f<T>(); /* ... */ return t; !
};
Read a file into a vector of strings:
vector<string> V;
copy(istream_iterator<string>(cin), istream_iterator<string>(),
back_inserter(V));
istream_iterator
You can template bitfields.
template <size_t X, size_t Y>
struct bitfield
{
char left : X;
char right : Y;
};
I have yet to come up with any purpose for this, but it sure as heck surprised me.
One of the most interesting grammars of any programming languages.
Three of these things belong together, and two are something altogether different...
SomeType t = u;
SomeType t(u);
SomeType t();
SomeType t;
SomeType t(SomeType(u));
All but the third and fifth define a SomeType object on the stack and initialize it (with u in the first two case, and the default constructor in the fourth. The third is declaring a function that takes no parameters and returns a SomeType. The fifth is similarly declaring a function that takes one parameter by value of type SomeType named u.
Getting rid of forward declarations:
struct global
{
void main()
{
a = 1;
b();
}
int a;
void b(){}
}
singleton;
Writing switch-statements with ?: operators:
string result =
a==0 ? "zero" :
a==1 ? "one" :
a==2 ? "two" :
0;
Doing everything on a single line:
void a();
int b();
float c = (a(),b(),1.0f);
Zeroing structs without memset:
FStruct s = {0};
Normalizing/wrapping angle- and time-values:
int angle = (short)((+180+30)*65536/360) * 360/65536; //==-150
Assigning references:
struct ref
{
int& r;
ref(int& r):r(r){}
};
int b;
ref a(b);
int c;
*(int**)&a = &c;
The ternary conditional operator ?: requires its second and third operand to have "agreeable" types (speaking informally). But this requirement has one exception (pun intended): either the second or third operand can be a throw expression (which has type void), regardless of the type of the other operand.
In other words, one can write the following pefrectly valid C++ expressions using the ?: operator
i = a > b ? a : throw something();
BTW, the fact that throw expression is actually an expression (of type void) and not a statement is another little-known feature of C++ language. This means, among other things, that the following code is perfectly valid
void foo()
{
return throw something();
}
although there's not much point in doing it this way (maybe in some generic template code this might come handy).
The dominance rule is useful, but little known. It says that even if in a non-unique path through a base-class lattice, name-lookup for a partially hidden member is unique if the member belongs to a virtual base-class:
struct A { void f() { } };
struct B : virtual A { void f() { cout << "B!"; } };
struct C : virtual A { };
// name-lookup sees B::f and A::f, but B::f dominates over A::f !
struct D : B, C { void g() { f(); } };
I've used this to implement alignment-support that automatically figures out the strictest alignment by means of the dominance rule.
This does not only apply to virtual functions, but also to typedef names, static/non-virtual members and anything else. I've seen it used to implement overwritable traits in meta-programs.