I have a class whose behavior I am trying to configure.
template<int ModeT, bool IsAsync, bool IsReentrant> ServerTraits;
Then later on I have my server object itself:
template<typename TraitsT>
class Server {…};
My question is for my usage above is my naming misnamed? Is my templated parameter actually a policy instead of a trait?
When is a templated argument a trait versus a policy?
Policies
Policies are classes (or class templates) to inject behavior into a parent class, typically through inheritance. Through decomposing a parent interface into orthogonal (independent) dimensions, policy classes form the building blocks of more complex interfaces. An often seen pattern is to supply policies as user-definable template (or template-template) parameters with a library-supplied default. An example from the Standard Library are the Allocators, which are policy template parameters of all STL containers
template<class T, class Allocator = std::allocator<T>> class vector;
Here, the Allocator template parameter (which itself is also a class template!) injects the memory allocation and deallocation policy into the parent class std::vector. If the user does not supply an allocator, the default std::allocator<T> is used.
As is typical in template-based polymporphism, the interface requirements on policy classes are implicit and semantic (based on valid expressions) rather than explicit and syntactic (based on the definition of virtual member functions).
Note that the more recent unordered associative containers, have more than one policy. In addition to the usual Allocator template parameter, they also take a Hash policy that defaults to std::hash<Key> function object. This allows users of unordered containers to configure them along multiple orthogonal dimensions (memory allocation and hashing).
Traits
Traits are class templates to extract properties from a generic type. There are two kind of traits: single-valued traits and multiple-valued traits. Examples of single-valued traits are the ones from the header <type_traits>
template< class T >
struct is_integral
{
static const bool value /* = true if T is integral, false otherwise */;
typedef std::integral_constant<bool, value> type;
};
Single-valued traits are often used in template-metaprogramming and SFINAE tricks to overload a function template based on a type condition.
Examples of multi-valued traits are the iterator_traits and allocator_traits from the headers <iterator> and <memory>, respectively. Since traits are class templates, they can be specialized. Below an example of the specialization of iterator_traits for T*
template<T>
struct iterator_traits<T*>
{
using difference_type = std::ptrdiff_t;
using value_type = T;
using pointer = T*;
using reference = T&;
using iterator_category = std::random_access_iterator_tag;
};
The expression std::iterator_traits<T>::value_type makes it possible to make generic code for full-fledged iterator classes usable even for raw pointers (since raw pointers don't have a member value_type).
Interaction between policies and traits
When writing your own generic libraries, it is important to think about ways users can specialize your own class templates. One has to be careful, however, not to let users fall victim to the One Definition Rule by using specializations of traits to inject rather than to extract behavior. To paraphrase this old post by Andrei Alexandrescu
The fundamental problem is that code that doesn't see the specialized
version of a trait will still compile, is likely to link, and
sometimes might even run. This is because in the absence of the
explicit specialization, the non-specialized template kicks in, likely
implementing a generic behavior that works for your special case as
well. Consequently, if not all the code in an application sees the
same definition of a trait, the ODR is violated.
The C++11 std::allocator_traits avoids these pitfalls by enforcing that all STL containers can only extract properties from their Allocator policies through std::allocator_traits<Allocator>. If users choose not to or forget to supply some of the required policy members, the traits class can step in and supply default values for those missing members. Because allocator_traits itself cannot be specialized, users always have to pass a fully defined allocator policy in order to customize their containers memory allocation, and no silent ODR violations can occur.
Note that as a library-writer, one can still specialize traits class templates (as the STL does in iterator_traits<T*>), but it is good practice to pass all user-defined specializations through policy classes into multi-valued traits that can extract the specialized behavior (as the STL does in allocator_traits<A>).
UPDATE: The ODR problems of user-defined specializations of traits classes happen mainly when traits are used as global class templates and you cannot guarantee that all future users will see all other user-defined specializations. Policies are local template parameters and contain all the relevant definitions, allowing them to be user-defined without interference in other code. Local template parameters that only contain type and constants -but no behaviorally functions- might still be called "traits" but they would not be visible to other code like the std::iterator_traits and std::allocator_traits.
I think you will find the best possible answer to your question in this book by Andrei Alexandrescu. Here, I will try to give just a short overview. Hopefully it will help.
A traits class is class that is usually intended to be a meta-function associating types to other types or to constant values to provide a characterization of those types. In other words, it is a way to model properties of types. The mechanism normally exploits templates and template specialization to define the association:
template<typename T>
struct my_trait
{
typedef T& reference_type;
static const bool isReference = false;
// ... (possibly more properties here)
};
template<>
struct my_trait<T&>
{
typedef T& reference_type;
static const bool isReference = true;
// ... (possibly more properties here)
};
The trait metafunction my_trait<> above associates the reference type T& and the constant Boolean value false to all types T which are not themselves references; on the other hand, it associates the reference type T& and the constant Boolean value true to all types T that are references.
So for instance:
int -> reference_type = int&
isReference = false
int& -> reference_type = int&
isReference = true
In code, we could assert the above as follows (all the four lines below will compile, meaning that the condition expressed in the first argument to static_assert() is satisfied):
static_assert(!(my_trait<int>::isReference), "Error!");
static_assert( my_trait<int&>::isReference, "Error!");
static_assert(
std::is_same<typename my_trait<int>::reference_type, int&>::value,
"Error!"
);
static_assert(
std::is_same<typename my_trait<int&>::reference_type, int&>::value,
"Err!"
);
Here you could see I made use of the standard std::is_same<> template, which is itself a meta-function that accepts two, rather than one, type argument. Things can get arbitrarily complicated here.
Although std::is_same<> is part of the type_traits header, some consider a class template to be a type traits class only if it acts as a meta-predicate (thus, accepting one template parameter). To the best of my knowledge, however, the terminology is not clearly defined.
For an example of usage of a traits class in the C++ Standard Library, have a look at how the Input/Output Library and the String Library are designed.
A policy is something slightly different (actually, pretty different). It is normally meant to be a class that specifies what the behavior of another, generic class should be regarding certain operations that could be potentially realized in several different ways (and whose implementation is, therefore, left up to the policy class).
For instance, a generic smart pointer class could be designed as a template class that accepts a policy as a template parameter for deciding how to handle ref-counting - this is just a hypothetical, overly simplistic, and illustrative example, so please try to abstract from this concrete code and focus on the mechanism.
That would allow the designer of the smart pointer to make no hard-coded commitment as to whether or not modifications of the reference counter shall be done in a thread-safe manner:
template<typename T, typename P>
class smart_ptr : protected P
{
public:
// ...
smart_ptr(smart_ptr const& sp)
:
p(sp.p),
refcount(sp.refcount)
{
P::add_ref(refcount);
}
// ...
private:
T* p;
int* refcount;
};
In a multi-threaded context, a client could use an instantiation of the smart pointer template with a policy that realizes thread-safe increments and decrements of the reference counter (Windows platformed assumed here):
class mt_refcount_policy
{
protected:
add_ref(int* refcount) { ::InterlockedIncrement(refcount); }
release(int* refcount) { ::InterlockedDecrement(refcount); }
};
template<typename T>
using my_smart_ptr = smart_ptr<T, mt_refcount_policy>;
In a single-threaded environment, on the other hand, a client could instantiate the smart pointer template with a policy class that simply increases and decreases the counter's value:
class st_refcount_policy
{
protected:
add_ref(int* refcount) { (*refcount)++; }
release(int* refcount) { (*refcount)--; }
};
template<typename T>
using my_smart_ptr = smart_ptr<T, st_refcount_policy>;
This way, the library designer has provided a flexible solution that is capable of offering the best compromise between performance and safety ("You don't pay for what you don't use").
If you're using ModeT, IsReentrant, and IsAsync to control the behaviour of the Server, then it's a policy.
Alternatively, if you are want a way to describe the characteristics of the server to another object, then you could define a traits class like so:
template <typename ServerType>
class ServerTraits;
template<>
class ServerTraits<Server>
{
enum { ModeT = SomeNamespace::MODE_NORMAL };
static const bool IsReentrant = true;
static const bool IsAsync = true;
}
Here are a couple of examples to clarify Alex Chamberlain's comment:
A common example of a trait class is std::iterator_traits. Let's say we have some template class C with a member function which takes two iterators, iterates over the values, and accumulates the result in some way. We want the accumulation strategy to be defined as part of the template too, but will use a policy rather than a trait to achieve that.
template <typename Iterator, typename AccumulationPolicy>
class C{
void foo(Iterator begin, Iterator end){
AccumulationPolicy::Accumulator accumulator;
for(Iterator i = begin; i != end; ++i){
std::iterator_traits<Iterator>::value_type value = *i;
accumulator.add(value);
}
}
};
The policy is passed in to our template class, while the trait is derived from the template parameter. So what you have is more akin to a policy. There are situations where traits are more appropriate, and where policies are more appropriate, and often the same effect can be achieved with either method leading to some debate about which is most expressive.
Policies are passed through the API by the user to actively choose which code paths should be followed inside a certain interface.
Traits on the other hand are used by the library author to select certain overloads based on what the user passes into the API.
Traits are a way of the library author reacting to the user input, whereas policies are a way for the user to actively influence the library behaviour.
Related
Hello Stackoverflow community,
I've been really confused on the concepts syntax and am having a hard time getting started.
I would like to create a polymorphic interface for two types of operator types: unary and binary and opted to try out the concept feature in c++20.
Not sure if it matters, but I used a CRTP create my unary functor compatible with binary functors, however I would like to get rid of that. Here's what I have so far:
template <typename T>
concept UnaryMatrixOperatable = requires(T _op) {
_op.template operate(std::unique_ptr<Matrix::Representation>{});
{_op.template operate() } -> same_as<std::unique_ptr<Matrix::Representation>>;
};
class ReLU : public UnaryAdapter<ReLU> {
public:
std::unique_ptr<Matrix::Representation> operate(
const std::unique_ptr<Matrix::Representation>& m);
};
static_assert(UnaryMatrixOperatable<ReLU>);
However, I am getting a compilation error, presumably because I am not doing some sort of template specialization for a const matrix & type?
include/m_algorithms.h:122:13: error: static_assert failed
static_assert(UnaryMatrixOperatable<ReLU>);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/m_algorithms.h:122:27: note: because 'Matrix::Operations::Unary::ReLU' does not satisfy 'UnaryMatrixOperatable'
static_assert(UnaryMatrixOperatable<ReLU>);
^
include/m_algorithms.h:53:26: note: because '_op.template operate(std::unique_ptr<Matrix::Representation>{})' would be invalid: 'operate' following the 'template' keyword does not refer to a template
_op.template operate(std::unique_ptr<Matrix::Representation>{});
^
Thanks for all the help in advance, this design in my code has been problematic for over a week so I'm determined to find a clean way to fix it! Thanks.
Concepts are not base classes, and you should not treat concept requirements like base class interfaces. Base classes specify exact function signatures that derived classes must implement.
Concepts specify behavior that must be provided. So you explain what that behavior is.
The behavior you seem to want is that you can pass an rvalue of a unique pointer to an operate member function. So... say that.
template <typename T>
concept UnaryMatrixOperatable = requires(T _op, std::unique_ptr<Matrix::Representation> mtx)
{
_op.operate(std::move(mtx));
};
There's no need for template here because you do not care if operate is a template function. It's not important in the slightest to your code if any particular T happens to implement operate as a template function or not. You're going to call it this way, so the user must specify some function interface that can be called a such.
The same goes for the zero-argument version. Though your interface should probably make it much more clear that you're moving from the unique pointer in question:
template <typename T>
concept UnaryMatrixOperatable = requires(T _op, std::unique_ptr<Matrix::Representation> mtx)
{
_op.operate(std::move(mtx));
{ std::move(_op).operate() } -> std::same_as<decltype(mtx)>;
};
In any case, the other reason you'll get a compile error is that your interface requires two functions: one that gets called with an object and one that does not. Your ReLu class only provides one function that pretends to do both.
Often when writing templated code, I find myself needing to store an instance of the template type in a member variable. For example, I might need to cache a value to be used later on. I would like to be able to write my code as:
struct Foo
{
template<typename T>
T member;
template<typename T>
void setMember(T value)
{
member<T> = value;
}
template<typename T>
T getMember()
{
return member<T>;
}
};
Where members are specialized as they are used. My question:
Is such templated member variable possible with current C++ generative coding facilities?
If not, are there any proposals for such a language feature?
If not, are there any technical reasons why such a thing is not possible?
It should be obvious that I do not want to list all possible types (e.g. in a std::variant) as that is not generative programming and would not be possible if the user of the library is not the same as the author.
Edit: I think this somewhat answers my 3rd question from above. The reason being that today's compilers are not able to postpone instantiation of objects to after the whole program has been parsed:
https://stackoverflow.com/a/27709454/3847255
This is possible in the library by combining existing facilities.
The simplest implementation would be
std::unordered_map<std::type_index, std::any>
This is mildly inefficient since it stores each std::type_index object twice (once in the key and once inside each std::any), so a std::unordered_set<std::any> with custom transparent hash and comparator would be more efficient; this would be more work though.
Example.
As you say, the user of the library may not be the same as the author; in particular, the destructor of Foo does not know which types were set, but it must locate those objects and call their destructors, noting that the set of types used may be different between instances of Foo, so this information must be stored in a runtime container within Foo.
If you're wary about the RTTI overhead implied by std::type_index and std::any, we can replace them with lower-level equivalents. For std::type_index you can use a pointer to a static tag variable template instantiation (or any similar facility), and for std::any you can use a type-erased std::unique_ptr<void, void(*)(void*)> where the deleter is a function pointer:
using ErasedPtr = std::unique_ptr<void, void(*)(void*)>;
std::unordered_map<void*, ErasedPtr> member;
struct tag {};
template<class T> inline static tag type_tag;
member.insert_or_assign(&type_tag<T>, ErasedPtr{new T(value), [](void* p) {
delete static_cast<T*>(p);
}});
Example. Note that once you make the deleter of std::unique_ptr a function pointer, it is no longer default-constructible, so we can't use operator[] any more but must use insert_or_assign and find. (Again, we've got the same DRY violation / inefficiency, since the deleter could be used as the key into the map; exploiting this is left as an exercise for the reader.)
Is such templated member variable possible with current C++ generative coding facilities?
No, not exactly what you describe. What is possible is to make the enclosing class a template and use the template parameters to describe the types of the class' members.
template< typename T >
struct Foo
{
T member;
void setMember(T value)
{
member = value;
}
T getMember()
{
return member;
}
};
In C++14 and later, there are variable templates, but you can't make a template non-static data member of a class.
If not, are there any proposals for such a language feature?
Not that I know of.
If not, are there any technical reasons why such a thing is not possible?
The primary reason is that that would make it impossible to define binary representation of the class. As opposed to templates, a class is a type, which means its representation must be fixed, meaning that at any place in the program Foo and Foo::member must mean the same things - same types, same object sizes and binary layout, and so on. A template, on the other hand, is not a type (or, in case of variable templates, is not an object). It becomes one when it is instantiated, and each template instantiation is a separate type (in case of variable templates - object).
For std::unique_ptr<T>, we have std::make_unique<T[]>();
For std::shared_ptr<T>, there's std::make_shared<T[]>().
A known aphorism in computer science is that we have either none of something, one of something, or arbitrarily many. Well, in this case we're talking about compound pointers, or pointer-like objects. And there are definitely others beyond these two (Example: smart pointers for CUDA-related memory).
Well, I would expect to have something like the following function:
template <typename Ptr>
inline Ptr make(size_t count);
template <typename T, class Deleter = std::default_delete<T>>
inline std::unique_ptr<T[], Deleter> make<std::unique_ptr<T, Deleter>>(size_t count)
{
return std::make_unique<T[]>(count);
}
template <typename T>
inline std::shared_ptr<T[]> make<std::shared_ptr<T[]>>(size_t count)
{
return std::make_shared<T[]>(count);
}
but within a traits class, e.g.
template <typename Ptr>
struct pointer_traits;
as pointer_traits<std::shared_ptr<T>>::make(). And this traits class would also have an element type, a raw pointer type (if one exists), etc. - similarly to the iterator traits class template, std::iterator_traits. It would also exist for the plain pointers, whose maker would be
template <typename T>
inline T* make<T*>(size_t count)
{
return new T[](count);
}
Can I find such this kind of traits class, or the equivalent thereof, in the standard library? I tried and failed... If it doesn't exist, has something similar been proposed/discussed by the standard committee?
Based on #NathanOlliver's insight and suggestion:
The standard library has a std::pointer_traits class, but that one does not have functions which actually perform allocation. It may be useful to propose this to the C++ standards committee, and I'm going to at least try to pursue it soon. Will post an update here if anything comes of it.
Catch-all traits classes like std::iterator_traits are useful by separating the properties of a type from its definition, so for example the properties may be made available before the definition is complete.
Defining traits in addition to each client class itself is inconvenient, because the traits typically also have a place as members. This is why the generic implementation of std::iterator_traits is defined in terms of its template argument's members.
template< typename it >
struct iterator_traits {
typedef typename it::category category;
typedef typename it::value_type value_type;
// etc
};
Isn't it easier, and less work for the compiler, to use inheritance instead?
template< typename t >
struct t_traits : public t {
t_traits() = delete; // Prevent runtime instances.
};
This fails to document the interface in the primary template, but there are other opportunities for that anyway.
It seems pointless to write lots of repetitive code to define a meta-container class, in an idiom which doesn't even guarantee prevent such abuse as creation at runtime.
Or maybe that's entirely backwards. In addition to std::iterator_traits we also have std::iterator, a pseudo-abstract base class with mostly the same members. Such redundancy is a code smell. Wouldn't it be better if custom iterators looked like this?
template<>
struct iterator_traits< struct my_iterator > {
typedef random_access_iterator_tag category;
typedef foo value_type;
...
};
struct my_iterator : iterator_traits< struct my_iterator > {
...
};
(For the sake of argument, let's ignore the fact that an actual std::iterator_traits specialization must be declared in namespace std. I'm trying to make a familiar illustration of something that might happen in user code.)
This is cleaner in that the idiom need not be violated to handle whatever exceptional case necessitated the fancy footwork in the first place. Instead of the primary traits template producing an internal error that the missing client class is unsuitable for something, there need not be any primary traits template at all.
It's conceptually better to separate qualities of a class from implementation of its services, regardless of whether that separation is necessary. BUT, this style does require breaking every client class into two pieces, including an explicit specialization, which is sort of ugly.
Is anyone familiar with this design space? I'm leaning toward the second idiom, although it looks unusual in practice. But there are probably ins and outs known to those who have trod here before.
The problem with user-defined traits as a specialization of a library type is that a library type belongs to the library. Defining an explicit specialization requires opening the library namespace, which is ugly.
Alternatives 1 and 2 can be combined into a best of both worlds pattern that
always allows optimal separation of concerns (by splitting a class into traits and implementation)
doesn't require splitting a class
never requires opening the library namespace
An extra bit of glue is needed in the form of an ADL based metafunction mapping any class to its traits.
template< typename t >
t traits_type_entry( t const & ); // Declared, never defined.
template< typename t >
using traits_type = decltype( traits_type_entry( std::declval< t >() ) );
By default, T serves as its own traits type as traits_type< T >::type is T. To change this for a given type t to a traits class t_traits, declare (but do not define) a function t_traits traits_type_entry( t const & ). This t_traits class may or may not be a base class of t; the traits_type facility doesn't care. Because the function will be found by argument-depenedent lookup, it may be declared as a friend function with no declaration at namespace scope.
Usage nested inside a class (just to make a difficult test-case) looks like this. For usual usage in a namespace just drop the friend keyword.
class outer_scope {
struct special;
struct special_traits {
typedef int value_type;
constexpr static int limit = 5;
};
friend special_traits traits_type_entry( special const & );
struct unspecial {
typedef double baz_type;
int table[ util::traits_type< special >::limit ];
};
struct special : special_traits {
void f() {
std::pair< typename util::traits_type< unspecial >::baz_type,
value_type >();
}
};
};
http://ideone.com/QztQ6i
Note, the t const & parameter to traits_type_entry can be simply t as long as the class is copyable and destructible.
Also, you could prevent declaring an object of (non-customized) trait type by having the primary template return a type derived from t with its constructor deleted, instead of t itself.
What could be the possible advantages/uses of having an empty class?
P.S:
This question might sound trivial to some of you but it is just for learning purpose and has no practical significance. FYI googling didn't help.
One use would be in template (meta-)programming: for instance, iterator tags are implemented as empty classes. The only purpose here is to pass around information at compilation time so you can check, if an iterator passed to e.g. a template function meets specific requirements.
EXAMPLE:
This is really simplified, just to ge an idea. Here the purpose of the tag class is to decide, which implementation of an algorithm to use:
class forward_iterator_tag {};
class random_access_iterator_tag {};
class MySimpleForwardIterator {
public:
typedef typename forward_iterator_tag tag;
// ...
};
class MySimpleRandomIterator {
public:
typedef typename random_access_iterator_tag tag;
// ...
};
template<class iterator, class tag>
void myfunc_int(iterator it, tag t) {
// general implementation of myfunc
}
template<class iterator>
void myfunc_int<iterator, forward_iterator_tag>(iterator it) {
// Implementation for forward iterators
}
template<class iterator>
void myfunc_int<iterator, random_access_iterator_tag>(iterator it) {
// Implementation for random access iterators
}
template<class iterator>
void myfunc(iterator it) {
myfunc_int<iterator, typename iterator::tag>(it);
}
(I hope I got this right, it's been a while since I used this ...)
With this code, you can call myfunc on an arbitrary iterator, and let the compiler choose the correct implementation depending on the iterator type (i.e. tag).
The following can be used to have a boost::variant which can hold an (SQL) NULL value for example.
class Null { };
typedef boost::variant<Null, std::string, int> Value;
To make it more useful things like operator== and operator<< are handy. For example:
std::ostream& operator<<(std::ostream &lhs, const Null &rhs)
{
lhs << "*NULL*";
return lhs;
}
int main()
{
Variant v("hello");
std::cout << v << std::endl;
v = Null();
std::cout << v << std::endl;
...
}
Will give:
hello
*NULL*
In the STL, Standard Template Library of the C++, for example you have
template<class _Arg,
class _Result>
struct unary_function
{ // base class for unary functions
typedef _Arg argument_type;
typedef _Result result_type;
};
When defining a functor, you can inherit unary_function, and then you have the typedef defined automatically at your disposal.
An empty class could be used as a "token" defining something unique; in certain patterns, you want an implementation-agnostic representation of a unique instance, which has no value to the developer other than its uniqueness. One example is Unit of Work; you may not care one bit about what's going on inside your performer, but you want to tell that performer that the tasks you're telling it to perform are part of an atomic set. An empty class representing the Unit of Work to the outside world may be perfect in this case; almost anything a Unit of Work object could store or do (encapsulating a DB transaction, exposing Commit/Rollback behaviors) would start tying you to a particular implementation, but an object reference is useful to provide a unique but copyable and passable reference to the atomic set of tasks.
You can use it like a placeholder for checking purpose or as enabler to special functionality. For example in Java exist the "empty" interface Serializable used to specify if a class is serializable.
"empty" classes means classes which have no data members?
They typically declare typedefs or member functions, and you can extend them with your own classes.
Here is an interesting link with answers to why its allowed. You might find this helpful to find situations where it might be useful.
As others have said, often an empty class (or struct) is used a placeholder, a differentiator, a token, etc.
For example, a lot of people are unaware that there are "nothrow" versions of operator new. The syntax to invoke nothrow new is:
p = new(std::nothrow) Bar;
and std::nothrow is defined simply as
struct nothrow_t {}; //defined in namespace std
The answer by MartinStettner is fine though just to highlight an important point here: The concept of iterator tags or for that matter any tags in C++, is not strictly dependent on empty classes. The C++ tags, if stl writers would have wanted to, could well have been non-empty classes; that should work but then it won't add any additional value; at least for compile time acrobatics that it is usually reserved for.
For the sake of typeid
Suppose we have comparable interface Id. We need fill some container with unique instances of this interface. How to guarantee the uniqueness of Id instances produced by independent software parts? «Independent parts» means some different dynamic libraries, compiled by different programmers from different locations
One of decisions is to compare typeid of some type first. If typeid matches, convert and compare other implementation specific properties. C++ language guarantees uniqueness of any type within process memory. Which type should be used for this purpose? Any type with minimum resource consumption — empty one