While implementing a template class whose constructor takes:
vector of functions (functions are of type std::function<bool(const T&)>)
std::binary_function<bool,bool,bool> that I will use to accumulate results of applications of vector from 1) to certain value.
I want to be able to use std::plus() and std::multiplies() as second template parameter, but the problem is that depending on the function I need a corresponding neutral element (for std accumulate init value). For AND (std::multiplies) I need true (aka 1), for OR (std::plus) I need false (aka 0). I know I could just specialize the template and problem solved but I wonder if there is a way to get neutral element for a built in STL function.
If you're using gcc, you can use __gnu_cxx::identity_element, which is doing exactly what you're asking for.
If you're not, I don't think there is a general solution, as if there was, gcc wouldn't have implemented their own - you might just rewrite their implementation (which is actually just a couple of template specializations, as you expected).
Edit: the source code for this is on lines 78-98 of this file.
The usual solution here is traits. Rather than instantiate your
template on std::plus or whatever, you would instantiate it on a
traits class, which defines a typedef for std::plus, plus an
identity element (static const, with initializer), and anything else you
need. Something like:
struct OpTraitsAdd
{
typedef std::plus<int> Op;
static int const identity = 0;
};
struct OpTraitsMult
{
typedef std::multiplies<int> Op;
static int const identity = 1;
};
It's also possible to obtain the traits from the standard operator,
using explicit specialization:
template <typename Op> struct OpTraits;
template<>
struct OpTraits<std::plus<int> >
{
static int const identity = 0;
};
template<>
struct OpTraits<std::multiplies<int> >
{
static int const identity = 1;
};
In this case, you would instantiate your class over the operator, and
use OpTraits<Op>::identity when needed.
In both cases, of course, you do have to provide all of the necessary
traits, either as independent classes or as template specializations.
If the only two identity elements you need are 0 and 1, you might be
able to do it automatically with something like:
template <bool idIs0> struct IdImpl;
template<>
struct IdImpl<false>
{
static int value = 1;
};
template<>
struct IdImpl<true>
{
static int value = 0;
};
template <typename Op>
struct Id
{
static int value = ItImpl<Op(1, 0) == 1>::value;
};
This will not work pre-C++11, since Op(1, 0) is not a constant
epxression. I'm not sure about C++11; but I think that if
Op::operator() is declared constexpr, it should work. (I'd only
bother trying if I had to cover a lot of operators, including some that
clients might provide.)
Just to pick out one point from James's answer (and my comment to it). I think it deserves to be considered separately.
If you want to you can compute the identity at runtime, assuming that there really is an identity. It's !func(true, false).
If func::operator() is available and free of side-effects, as it is for std::plus and std::multiplies, then presumably any sensible compiler will actually compute that at compile time. But it doesn't need the value at compile time, so now your template could (if the caller wants) accept a std::function<bool(bool,bool)> instead of needing to know the actual accumulate operation at compile-time.
Related
If i have for example some template struct, and i want to give it a user-defined size for some member i can do it by passing a value to constructor like so:
template <typename T>
struct Foo {
int m_size;
Foo(int u_size)
:
m_size {u_size}
{
}
};
and i can also do it by having a non-type template parameter (kinda the way std::array does it), like so:
template <typename T, int u_size>
struct Foo {
int m_size;
Foo()
:
m_size {u_size}
{
}
};
My question is, what is the difference between these two methods, and when is it useful to use either of them?
You are using u_size to determine the initializer for the member m_size. The difference between the two examples boils down to Foo<T,i> being a different type than Foo<T,j>. Other than being instantiations of the same template (which usually does not mean much) they are totally unrelated. On the other hand, in the first case, any Foo<T> is of the same type Foo<T>, no matter what was the initial value for the member.
If m_size changes at runtime, it is questionable to require an instance that uses 42 as initial value and an instance that uses 24 as initial value to be of different types.
Maybe m_size does not change at runtime, then it can make sense to have the initial value as part of the type (like eg with std::array). Maybe it does change at runtime, but nevertheless there are reasons to have the initial value baked into the type. There is no "better" Or "worse", it depends what you want/need.
Is it possible to check if a template type has been instantiated at compile time so that I can use this information in an enable_if specialization?
Let's say I have
template <typename T> struct known_type { };
Can I somehow define some is_known_type whose value is true if known_type is instantiated at compile time?
It's possible to do this if you leverage the fact that specific expressions may or may not be used in places where constexprs are expected, and that you can query to see what the state is for each candidate you have. Specifically in our case, the fact that constexprs with no definition cannot pass as constant expressions and noexcept is a guarantee of constant expressions. Hence, noexcept(...) returning true signals the presence of a properly defined constexpr.
Essentially, this treats constexprs as Yes/No switches, and introduces state at compile-time.
Note that this is pretty much a hack, you will need workarounds for specific compilers (see the articles ahead) and this specific friend-based implementation might be considered ill-formed by future revisions of the standard.
With that out of the way...
User Filip Roséen presents this concept in his article dedicated specifically to it.
His example implementation is, with quoted explanations:
constexpr int flag (int);
A constexpr function can be in either one of two states; either it is
usable in a constant-expression, or it isn't - if it lacks a
definition it automatically falls in the latter category - there is no
other state (unless we consider undefined behavior).
Normally, constexpr functions should be treated exactly as what they
are; functions, but we can also think of them as individual handles to
"variables" having a type similar to bool, where each "variable" can
have one of two values; usable or not-usable.
In our program it helps if you consider flag to be just that; a handle
(not a function). The reason is that we will never actually call flag
in an evaluated context, we are only interested in its current state.
template<class Tag>
struct writer {
friend constexpr int flag (Tag) {
return 0;
}
};
writer is a class template which, upon instantiation, will create a
definition for a function in its surrounding namespace (having the
signature int flag (Tag), where Tag is a template-parameter).
If we, once again, think of constexpr functions as handles to some
variable, we can treat an instantiation of writer as an
unconditional write of the value usable to the variable behind the
function in the friend-declaration.
template<bool B, class Tag = int>
struct dependent_writer : writer<Tag> { };
I would not be surprised if you think dependent_writer looks like a
rather pointless indirection; why not directly instantiate writer
where we want to use it, instead of going through dependent_writer?
Instantiation of writer must depend on something to prevent immediate instantiation, and;
dependent_writer is used in a context where a value of type bool can be used as dependency.
template<
bool B = noexcept (flag (0)),
int = sizeof (dependent_writer<B>)
>
constexpr int f () {
return B;
}
The above might look a little weird, but it's really quite simple;
will set B = true if flag(0) is a constant-expression, otherwise B = false, and;
implicitly instantiates dependent_writer (sizeof requires a completely-defined type).
The behavior can be expressed with the following pseudo-code:
IF [ `int flag (int)` has not yet been defined ]:
SET `B` = `false`
INSTANTIATE `dependent_writer<false>`
RETURN `false`
ELSE:
SET `B` = `true`
INSTANTIATE `dependent_writer<true>`
RETURN `true`
Finally, the proof of concept:
int main () {
constexpr int a = f ();
constexpr int b = f ();
static_assert (a != b, "fail");
}
I applied this to your particular problem. The idea is to use the constexpr Yes/No switches to indicate whether a type has been instantiated. So, you'll need a separate switch for every type you have.
template<typename T>
struct inst_check_wrapper
{
friend constexpr int inst_flag(inst_check_wrapper<T>);
};
inst_check_wrapper<T> essentially wraps a switch for whatever type you may give it. It's just a generic version of the original example.
template<typename T>
struct writer
{
friend constexpr int inst_flag(inst_check_wrapper<T>)
{
return 0;
}
};
The switch toggler is identical to the one in the original example. It comes up with the definition for the switch of some type that you use. To allow for easy checking, add a helper switch inspector:
template <typename T, bool B = noexcept(inst_flag(inst_check_wrapper<T>()))>
constexpr bool is_instantiated()
{
return B;
}
Finally, the type "registers" itself as initialized. In my case:
template <typename T>
struct MyStruct
{
template <typename T1 = T, int = sizeof(writer<MyStruct<T1>>)>
MyStruct()
{}
};
The switch is turned on as soon as that particular constructor is asked for. Sample:
int main ()
{
static_assert(!is_instantiated<MyStruct<int>>(), "failure");
MyStruct<int> a;
static_assert(is_instantiated<MyStruct<int>>(), "failure");
}
Live on Coliru.
No, a compile time check for not instantiated classes is not possible. However you might establish a (static) map of instantiated classes (in debug build), which you can check at run time.
However, analyzing the linked binary by comparing a list of expected instantiated classes with actually instantiated classes should be possible (but that is past compile time and past my knowledge).
There's is no way to do that. So I would say: No.
I have a template class with a callable type-parameter <typename Callable>.
I know that Callable indeed creates a callable object, and is often a lambda.
In my particular case, I also know the number (arity) and type of arguments (just one).
How can I get the return type of this callable type Callable on VS2010?
See std::result_of.
Pretending the object is invoked with one int argument, you could do things like:
using return_type = typename std::result_of<Callable(int)>::type;
This isn't generally possible.
There are multiple ways to have callable types, including lambdas and structs that overload operator().
C++ does not have nearly the type of reflection that languages like C# do, and it is impossible to do with the tools that C++ offers.
If all you want is to store the result of that "callable" into a variable, then you can just use auto.
If you actually want to do stuff with the result based on its type, then this question might help.
Basically, add this to your code.
template <typename T, typename U>
struct same_type
{
static const bool value = false;
};
template <typename T>
struct same_type< T, T >
{
static const bool value = true;
};
Then, if you have auto result = func(param);, where func is of type Callable, you can check the type of result with the following:
if (same_type<decltype(result), int>().value)
{
// code, knowing that result is of type int
}
else if (same_type<decltype(result), const char*>().value)
{
// code, knowing that result is of type const char*
}
// else if ... etc.
I tried various approaches, but support for C++11 in VS2010 is only partial and most approaches simply didn't compile.
What did finally work (on VS2010) is the following:
// When arity is known
typedef decltype(callbackInstance0()) return_type0;
typedef decltype(callbackInstance1(argInstance)) return_type1;
Where callbackInstanceX is the actual callable object to be used and argInstance is the actual arg to be passed to callbackInstance.
Note that this is not a general solution (though sufficient in my case) because:
It cannot be used outside of a function where you don't have actual instances of these types, but only the types, as in the class definition;
The callable arity must be known.
The size of std::array is known at compile time, but the size member function isn't static. Is there any reason for that? It's slightly inconvenient not to be able to calculate the size without instantiating an object. (Well, I know about std::tuple_size specialization, but it doesn't work for classes derived from std::array.)
There is no good reason for that. In fact, boost::array<T, N>, the precursor of std::array<T,N>, actually defines static size_t size(){return N;} (although a modern more useful version should use constexpr also).
I agree with the OP that this is an unfortunate omission and underexplotaition of the language features.
Problem
I faced this problem before and the logic leads to a couple of solutions. The OP situation is the following: you have a class that derives from std::array and you need to access to the size at compile time.
#include<array>
template<class T...>
struct myarray : std::array< something that depends on T... >{
... very cool functions...
};
and later you have
template<class Array, size_t N = ???>
functionOnArrayConcept(Array const& a){...}
Where you need to know N at compile time.
As it is now, there is no code ??? that you can write that works both for std::array and myarray, because std::tuple_size<myarray<...>> will not work.
Solution
(this was suggested by #T.C. here Access maximum template depth at compile? . I am just copying it here.)
template<class T, std::size_t N>
auto array_size_impl(const std::array<T, N>&)
-> std::integral_constant<std::size_t, N>;
template<class Array>
using array_size = decltype(array_size_impl(std::declval<const Array&>()));
template<class Array>
constexpr auto static_size() -> decltype(array_size<Array>::value){
return array_size<Array>::value;
}
template<class Array>
constexpr auto static_size(Array const&) -> decltype(static_size<Array>()){
return static_size<Array>();
}
Now you can use it as this:
template<class Array, size_t N = static_size<Array>()>
functionOnArrayConcept(Array const& a){...}
If you are using std::tuple_size already, unfortunately (I think) you need to specialize std::tuple_size for each of your derived classes:
namespace std{
template<class... T> // can be more complicated if myarray is not parametrized by classes only
struct tuple_size<myclass<T...>> : integral_constant<size_t, static_size<myclas<T...>>()>{};
}
(In my opinion this is caused by another mistake in the STL design that std::tuple_size<A> doesn't have the default template<class A> struct tuple_size : A::size(){}.)
The solutions beyond this point are near obsolete compared to #T.C.
solution described above. I'll keep them here for reference only.
Solution 1 (idiomatic)
If the function is decoupled from you class you have to use std::tuple_size because that is the only standard way of accessing the size of std::array at compile time. Therefore you have to do this, 1) provide a specialization of std::tuple_size and if you can control myclass, 2) std::array doesn't have static size() but your derived class could (that simplifies the solution).
So, this can be a pretty general solution within the framework of STD, that consists in the specialization of std::tuple_size.
(Unfortunately providing specialization in std:: sometimes is the only way to make real generic code. See http://en.cppreference.com/w/cpp/language/extending_std)
template<class... T>
struct myarray : std::array<...something that depends on T...>{
... very cool functions...
static constexpr size_t size(){return std::tuple_size<std::array<...something that depends on T...>>::value;}
};
namespace std{
// specialization of std::tuple_size for something else that `std::array<...>`.
template<class... T> // can be more complicated if myarray is not parametrized by classes only
struct tuple_size<myclass<T...>> : integral_constant<size_t, myclass<T...>::size()>{};
}
// now `functionOnArrayConcept` works also for `myarray`.
(static size_t size() can be called differently, and there may be other ways to deduce the size of the base of myarray without adding any static function to size.)
Note
In the compilers I tried the following trick doesn't work. If this worked, the whole discussion would be less important, because std::tuple_size wouldn't be so necessary.
template<class ArrayConcept, size_t N = ArrayConcept{}.size()> // error "illegal expression", `std::declval<ArrayConcept>()` doesn't work either.
functionOnArrayConcept(ArrayConcept const& a){...}
Conceptualization
Due to this shortcoming in the implementation (or specification?) of std::array by which the only way to extract the compile time size is through std::tuple_size. Then std::tuple_size is conceptually part of the necessary interface of std::array. Therefore when you inherit from std::array you have also "inherit" std::tuple_size in some sense. And unfortunately you need to do this for further derivations. This is the concept behind this answer.
Solution 2 (a GNU hack)
If you are using GNU's STD library (that includes gcc and clang), there is a hack that can be used without adding any code, and that is by using the _M_elems member which is of (member) type ::_AT_Type::_Type (a.k.a. type T[N]) of std::array<T, N>.
This function will effectively behave like a static function ::size() (except that it cannot be used for instances of an object) of std::array or any type derived from std::array.
std::extent<typename ArrayType::_AT_Type::_Type>::value
which can be wrapped into:
template<class ArrayType>
constexpr size_t array_size(){
return std::extent<typename ArrayType::_AT_Type::_Type>::value
}
This work because the member type _AT_Type::_Type is inherited. (I wonder why GNU left this implementation detail public. Another omission?)
Solution 3 (a portable hack)
Finally, a solution using template recursion one can figure out what is the dimension of the base std::array.
template<class Array, size_t N=0, bool B = std::is_base_of<std::array<typename Array::value_type, N>, Array>::value>
struct size_of : size_of<Array, N + 1, std::is_base_of<std::array<typename Array::value_type, N+1>, Array>::value>{};
template<class Array, size_t N>
struct size_of<Array, N, true> : std::integral_constant<size_t, N>{};
// this is a replacement for `static Array::size()`
template<class Array, size_t N = size_of<Array>::value>
constexpr size_t static_size(){return N;}
// this version can be called with an object like `static Array::size()` could
template<class Array, size_t N = size_of<Array>::value>
constexpr size_t static_size(Array const&){return N;}
This is how one will get:
struct derived : std::array<double, 3>{};
static_assert( static_size<std::array<double, 3>>() == 3 );
static_assert( static_size<derived>() == 3 );
constexpr derived d;
static_assert( static_size(d) == 3 );
If this function is called with some type unrelated to std::array, it will give a recursion error. If you want a "soft" error instead, you have to add the specialization.
template<class Array>
struct size_of<Array, 250, false> {};
where 250 stands for a large number but smaller than the recursion limit. (I don't know how to get this number automatically, I only know the the recursion limit in my compiler is 256.)
Since C++11 you can use std::tuple_size on std::array to obtain the size as a compile time constant. See
http://en.cppreference.com/w/cpp/container/array/tuple_size
It can indeed be static, however, this would break "container" interface which won't play well with other generic algorithms that do expect containers to have size() member function. There is nothing to worry about, though, as std::array::size() is a constexpr function, so there is absolutely no overhead associated with it.
UPDATE:
Mr. Jrok have pointed out that one can call static member functions with "normal" syntax. Below is an example when it won't:
#include <array>
struct array {
static unsigned int size()
{
return 0;
}
};
template <typename T>
static auto do_stuff(T& data) -> decltype(data.size())
{
typedef decltype(data.size()) size_type;
size_type (T::*size_calc)() const = &T::size;
size_type n = 0;
for (size_type i = 0, e = (data.*size_calc)(); i < e; ++i)
++n;
return n;
}
int main()
{
// Below is fine:
std::array<int, 5> data { 1, 2, 3, 4, 5 };
do_stuff(data);
// This, however, won't work as "size()" is not a member function.
#if 0
array fake;
do_stuff(fake);
#endif
}
array::size is constexpr, so unless the stored type has a constructor or destructor, the operation array_t().size() is very unlikely to have any runtime effect. You can embed it in a template argument to ensure it doesn't. It does otherwise look like runtime code, though.
I think that it's nonstatic simply for uniformity with other containers. For example, you can form a pointer-to-member-function to it. Discovering the true rationale of anything often takes tough research, though. It could be that the authors never thought of it.
The other thing that comes to mind is that some special functions such as operator () () cannot be static, so any opportunistic application of static can only be piecemeal. Generic problems are better solved in uniform fashion, even if it means changing the core language.
You can re-declare a same-typed empty std::array (which should get optimized out) and take the size of that. For example:
// Pretend this is an expensive initialization; e.g., a function return value.
std::array<char, 0x123> some_array{1,2,3};
using type_of_some_array = decltype(some_array);
// Find the size without accessing the array.
auto constexpr size_of_some_array = type_of_some_array().size();
std::cout << size_of_some_array << std::endl;
compiles to:
00000000004006f0 <main>:
4006f0: 48 83 ec 08 sub $0x8,%rsp
4006f4: be 23 01 00 00 mov $0x123,%esi
4006f9: bf 60 10 60 00 mov $0x601060,%edi
4006fe: e8 ad ff ff ff callq 4006b0 <_ZNSo9_M_insertImEERSoT_#plt>
...
[No issues found when using size_of_some_array as a template parameter: which was counter-alluded to in the comments on #Potatoswatter's answer.]
Note that the Microsoft Visual C++ doesn't currently support constexpr (http://msdn.microsoft.com/en-us/library/hh567368.aspx), so the following valid code won't work:
array<int,3> dog;
array<double, dog.size( )> cat;
The following class provides a compile time static variable:
/**
* hack around MSVC's 2012 lack of size for const expr
*/
template <typename T, int N>
struct vcarray : public std::array<T,N> {
static const size_t ArraySize= N;
};
which can be used as:
vcarray<double,3> cat;
vcarray<double,cat.ArraySize> dog;
In my opinion it does not make sense to make the size member function static insofar as it provides no added value. It is possible to make it static, but you gain nothing from it.
The way the array class is designed, you can query the size of a given array object without explicitly knowing/remembering its exact type (which includes its size) at that location where you need the size. This is a convenience, and it removes the opportunity to make copy/edit errors. You can write code like this:
std::array<int, 5> blah;
// 50 lines of code
do_something_with(blah.size()); // blah knows its size
As you can see, at the location where I'm consuming the array's size, I don't actually remember what it was, but my code will work anyway, regardless of what the value actually is, and regardless whether maybe one day I change the array's type to be a different size.
Since the size function merely returns a template parameter, the compiler can trivially prove that the return value is a compile-time constant and optimize accordingly too (the function is also constexpr, so you can also use the return value as template parameter or enumeration).
Now what will be different if we make the size member function static?
If size was a static function, you could still use the static member function in the exact same way (that is, on an object instance, in a "not static way"), but that would be "cheating". After all, this is something that already works anyway, whether the member is static or not.
Further, you now have the possibility of invoking the member function without an object instance. While this seems like a good thing at first glance it really is no advantage at all for the array class template (...where the returned size is a template parameter).
In order to call a member function without an object (that is, in a "static member function way"), you must properly qualify the function with the class name and its proper template parameters.
In other words, you must write something like:
std::array<int, 5> blah;
// 50 lines of code
do_something_with(std::array<int,5>::size()); // I must tell size what to return
Now what have we gained from calling the size function? Nothing at all. In order to call the function, we needed to provide the correct template parameters, which includes the size.
That means no more and no less than that we must supply the information that we wish to query. Calling the function doesn't tell us anything we didn't already know.
In C++ you can create templates using a non-type template parameter like this:
template< int I >
void add( int& value )
{
value += I;
}
int main( int argc, char** argv )
{
int i = 10;
add< 5 >( i );
std::cout << i << std::endl;
}
Which prints "15" to cout. What is the use for this? Is there any reason for using a non-type template parameter instead of something more conventional like:
void add( int& value, int amount )
{
value += amount;
}
Sorry if this has already been asked (I looked but couldn't find anything).
There are many applications for non-type template arguments; here are a few:
You can use non-type arguments to implement generic types representing fixed-sized arrays or matrices. For example, you might parameterize a Matrix type over its dimensions, so you could make a Matrix<4, 3> or a Matrix<2, 2>. If you then define overloaded operators for these types correctly, you can prevent accidental errors from adding or multiplying matrices of incorrect dimensions, and can make functions that explicitly communicate the expected dimensions of the matrices they accept. This prevents a huge class of runtime errors from occur by detecting the violations at compile-time.
You can use non-type arguments to implement compile-time function evaluation through template metaprogramming. For example, here's a simple template that computes factorial at compile-time:
template <unsigned n> struct Factorial {
enum {
result = n * Factorial<n - 1>::result
};
};
template <> struct Factorial<0> {
enum {
result = 1
};
};
This allows you to write code like Factorial<10>::result to obtain, at compile-time, the value of 10!. This can prevent extra code execution at runtime.
Additionally, you can use non-type arguments to implement compile-time dimensional analysis, which allows you to define types for kilograms, meters, seconds, etc. such that the compiler can ensure that you don't accidentally use kilograms where you meant meters, etc.
Hope this helps!
You're probably right in this case, but there are cases where you need to know this information at compile time:
But how about this?
template <std::size_t N>
std::array<int, N> get_array() { ... }
std::array needs to know its size at compile time (as it is allocated on the stack).
You can't do something like this:
std::array<int>(5);
Well, this the typical choice between compile-time polymorphism and run-time polymorphism.
From the wording of your question in appears that you see nothing unusual in "ordinary" template parameters, while perceiving non-type parameters as something strange and/or redundant. In reality the same issue can be applied to template type parameters (what you called "ordinary" parameters) as well. Identical functionality can often be implemented either through polymorphic classes with virtual functions (run-time polymorphism) or through template type parameters (compile-time polymorphism). One can also ask why we need template type parameters, since virtually everything can be implemented using polymorphic classes.
In case of non-type parameters, you might want to have something like this one day
template <int N> void foo(char (&array)[N]) {
...
}
which cannot be implemented with a run-time value.
In that particular instance, there's not really any advantage. But using template parameters like that, you can do a lot of things you couldn't do otherwise, like effectively bind variables to functions (like boost::bind), specify the size of a compile-time array in a function or class (std::array being a ready example of that), etc.
For instance, with that function, you write a function like
template<typename T>
void apply(T f) {
f(somenum);
}
Then you can pass apply a function:
apply(&add<23>);
That's an extremely simple example, but it demonstrates the principle. More advanced applications include applying functions to every value in a collection, calculating things like the factorial of a function at compile time, and more.
You couldn't do any of that any other way.
There are lots of reasons, like doing template metaprogramming (check Boost.MPL). But there is no need to go that far, C++11's std::tuple has an accessor std::get<i> that needs to be indexed at compile time, since the result is dependent on the index.
The most frequent use for a value parameter that I can think of is std::get<N>, which retrieves the Nth element of a std::tuple<Args...>. The second-most frequent use would be std::integral_constant and its main derivatives std::true_type and std::false_type, which are ubiquitous in any sort of trait classes. In fact, type traits are absolutely replete with value template parameters. In particular, there are SFINAE techniques which leverage a template of signature <typename T, T> to check for the existence of a class member.