C++14 will allow the creation of variables that are templated. The usual example is a variable 'pi' that can be read to get the value of the mathematical constant π for various types (3 for int; the closest value possible with float, etc.)
Besides that we can have this feature just by wrapping a variable within a templated struct or class, how does this mix with type conversions? I see some overlapping.
And other than the pi example, how would it work with non-const variables? Are there any usage examples to understand how to make the most of such a feature and what its purpose is?
And other than the pi example, how would it work with non-const
variables?
Currently, it seems to instantiate the variables separately for the type. i.e., you could assign 10 to n<int> and it would be different from the template definition.
template<typename T>
T n = T(5);
int main()
{
n<int> = 10;
std::cout << n<int> << " "; // 10
std::cout << n<double> << " "; // 5
}
If the declaration is const, it is readonly. If it's a constexpr, like all constexpr declarations, it has not much use outside constexpr(ressions).
Besides that we can have this feature just by wrapping a variable
within a templated struct or class, how does this mix with type
conversions?
It's meant to be a simple proposal. I am unable to see how it affects type conversions in a significant way. As I already stated, the type of the variable is the type you instantiated the template with. i.e., decltype(n<int>) is int. decltype((double)n<int>) is double and so on.
Any usage example to understand how to make the most of such a feature
and what its purpose is?
N3651 provides a succinct rationale.
Alas, existing C++ rules do not allow a template declaration to
declare a variable. There are well known workarounds for this
problem:
• use constexpr static data members of class templates
• use constexpr function templates returning the desired values
These workarounds have been known for decades and well documented.
Standard classes such as std::numeric_limits are archetypical
examples. Although these workarounds aren’t perfect, their drawbacks
were tolerable to some degree because in the C++03 era only simple,
builtin types constants enjoyed unfettered direct and efficient
compile time support. All of that changed with the adoption of
constexpr variables in C++11, which extended the direct and efficient
support to constants of user-defined types. Now, programmers are
making constants (of class types) more and more apparent in programs.
So grow the confusion and frustrations associated with the
workarounds.
...
The main problems with "static data member" are:
• they require "duplicate" declarations: once inside the class
template, once outside the class template to provide the "real"
definition in case the con- stants is odr-used.
• programmers are both miffed and confused by the necessity of providing twice the same
declaration. By contrast, "ordinary" constant declarations do not need
duplicate declarations.
...
Well known examples in this category are probably static member
functions of numeric_limits, or functions such as
boost::constants::pi<T>(), etc. Constexpr functions templates do not
suffer the "duplicate declarations" issue that static data members
have; furthermore, they provide functional abstraction. However, they
force the programmer to chose in advance, at the definition site, how
the constants are to be delivered: either by a const reference, or by
plain non- reference type. If delivered by const reference then the
constants must be systematically be allocated in static storage; if
by non-reference type, then the constants need copying. Copying isn’t
an issue for builtin types, but it is a showstopper for user-defined
types with value semantics that aren’t just wrappers around tiny
builtin types (e.g. matrix, or integer, or bigfloat, etc.) By
contrast, "ordinary" const(expr) variables do not suffer from this
problem. A simple definition is provided, and the decision of
whether the constants actually needs to be layout out in storage only
depends on the usage, not the definition.
we can have this feature just by wrapping a variable within a templated struct or class
Yes, but that would be gratuitous syntactic salt. Not healthy for the blood pressure.
pi<double> conveys the intent better than pi<double>::value. Short and to the point. That's enough of a reason in my book to allow and encourage this syntax.
Another practical example for C++14's variable templates is when you need a function for passing something into std::accumulate:
template<typename T>
T const & (*maxer) (T const &, T const &) = std::max<T>;
std::accumulate(some.begin(), some.end(), initial, maxer<float>);
Note that using std::max<T> is insufficient because it can't deduce the exact signature. In this particular example you can use max_element instead, but the point is that there is a whole class of functions that share this behavior.
I wonder whether something along these lines would be possible: (assuming availability of template lambdas)
void some_func() {
template<typename T>
std::map<int, T> storage;
auto store = []<typename T>(int key, const T& value) { storage<T>[key] = value; };
store(0, 2);
store(1, "Hello"s);
store(2, 0.7);
// All three values are stored in a different map, according to their type.
}
Now, is this useful?
As a simpler use, notice that the initialization of pi<T> uses explicit conversion (explicit call of a unary constructor) and not uniform initialization. Which means that, given a type radians with a constructor radians(double), you can write pi<radians>.
Well, you can use this to write compile time code like this:
#include <iostream>
template <int N> const int ctSquare = N*N;
int main() {
std::cout << ctSquare<7> << std::endl;
}
This is a significant improvement over the equivalent
#include <iostream>
template <int N> struct ctSquare {
static const int value = N*N;
};
int main() {
std::cout << ctSquare<7>::value << std::endl;
}
that people used to write to perform template metaprogramming before variable templates were introduced. For non-type values, we were able to do this since C++11 with constexpr, so template variables have only the advantage of allowing computations based on types to the variable templates.
TL;DR: They don't allow us to do anything we couldn't do before, but they make template metaprogramming less of a PITA.
I have a use case here.
template<typename CT> constexpr CT MARK = '%';
template<> constexpr wchar_t MARK<wchar_t> = L'%';
which are used in a string processing template.`
template <typename CT>
void ProcessString(const std::basic_string<CT>& str)
{
auto&& markpos = str.find(MARK<CT>);
...
}
Related
I have been looking into type_traits recently & was wondering why are they implemented as class templates whereas implementing them as functions could be more obvious & have a simpler syntax.
What I want to say is this syntax :-
int x = 5;
std::cout << is_same<int>(x);
Is more convincing & cleaner than the actual one ie :-
int x = 5;
std::cout << is_same <int, decltype(x)>::value;
This is just a case of curiosity. I just want to know the philosophy of the Standardization Committee in preferring the class method over the function method.
Versality. Most type traits have both X::value boolean constant and X::type type alias which can be used for tag dispatch.
Ability to partially specialize. You cannot have partial specialization for function, only full specializations and overloads. It is easy to call wrong function in presence of both specializations and overloads.
Compile-time evaluation. Most of type traits were invented in previous millenia, when constexpr functions were not avaliable. Even in constexpr functions you cannot pass values as parameter, as it might prevent compile-time evaluation.
You always have type, but sometimes it is all you have. Creating a function which does not work all the time is counterproductive, so we will not be able to rely on template parameter deduction anyway.
So I understand using var in C# makes sense because you have anonymous types that are compiler derived. C++ doesn't seem to have this feature (unless I'm wrong), so what is the point of having an auto keyword?
(It is kinda cool that unlike C#, auto does work for member/global variables, which is cool I guess, but doesn't seem enough to justify its existence).
auto has a lot of uses when it comes down to both generic programming and to save the programmer some typing.
For example, consider this. Would you rather type out:
std::unique_ptr<name::long_type::goes_here> g =
std::make_unique<name::long_type::goes_here>(1,2,3,4)
or:
auto g = std::make_unique<name::long_type::goes_here>(1,2,3,4)
Yes, they're both long but we know the return type and specifying it again is a bit cumbersome to type. This also goes for iterators:
for(auto i = vec.begin(); ...)
vs:
for(std::vector<type>::iterator i = vev.begin(); ...)
Its use in generic programming is also to figure out the return type of a function or if you're doing some generic algorithms where you don't know the type.
For example, consider a very basic example.
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
This allows the compiler to figure out the type of the add operation rather than us trying to figure it out ourselves. Note that in C++14 you can omit the trailing return type. Its uses in generic programming don't stop there either. If we wanted to work with any type of container as a wrapper function for algorithms we could use auto to help us with it. For example:
template<class Cont>
void my_sort(Cont&& cont) {
using std::begin;
auto first = begin(std::forward<Cont>(cont));
// work with the iterators here
}
In the future (C++14), auto can be used to make polymorphic lambdas as well such as:
[](auto a) { return a + 4; }
Which can be useful as well.
There are a number of uses for auto in C++
Anonymous function objects, aka closures, aka lambda instances. auto is the only way to store them. Types can also be generated derived off those types, and types on their backs, ad infinitum.
C++ can have quite complex types, such as the type of a non mutating iterator into an unordered map that uses a custom allocator and hashing function. typedef can mitigate this, but the type of a m.begin() having a particular name is not that informative: foo_iterator it = is as meaningful as auto foo_iterator =, and the auto one does not require boilerplate elsewhere.
Return type deduction uses the auto keyword, which is required to do some template functions work without huge amounts of traits boilerplate. Eliminating boilerplate is a common theme: C++s robust type system means that types can carry lots of information, and encoding it at every use can be counterproductive.
In some ducktype template code, the work to deduce the type of a variable is roughly the same as the work to code the variables value, and nearly identical in structure, some times literally: decltype(long expression) x = long expression;. auto eliminates that duplication.
Finally in C++1y, type deduction lambdas use auto to say that an argument is a deduced one. Sort of a light weight template. Talk to extend this to non lambdas is also in skunkworks.
HEre's a real life example where I could not, not use auto
I was trying to do a switch type statement in C++ where the return type is implementation specific and could not be declared easily. So using an 'auto' is probably the right way to resolve the type look up for the map declaration.
auto foo = boost::bind(&VegaFactory::load_commodity_one_leg,this,conn,_1);
std::map<std::string,decltype(foo)> methods;
methods.insert(std::make_pair("FOO",commodityOneLeg));
auto f = methods.find(bar);
// Call f here
C++ does have "anonymous" types - types you cannot refer to by name because the name is not available to you. This was the case even before C++11 and lambdas. Consider the following code:
class foo {
class bar {
public:
void baz() { }
};
public:
static bar func() { return bar(); }
};
foo::func().baz(); // OK, only the name "bar" is private
??? a = foo::func(); // Umm...
auto b = foo::func(); b.baz(); // Hooray!
Even if not actually declared in a private scope, it is often useful for a library to leave some types unspecified in its API - especially when heavily utilizing expression templates or other template metaprogramming where the type names can be arbitrarily long with all the nested template arguments. Even the standard itself does this - for instance, the result type of std::bind is not defined by the specification.
syntactic sugar
I rather say
auto i = mapping.begin();
over
std::map<int, int>::iterator i = mapping.begin();
It is well worth reading Herb Sutter's article Almost Always Auto for some great examples of why it's worth using auto over explicit types. The main advantages are the reduction in typing, and gives additional safety if the underlying types change. One of my favourite examples though is about how it reduces duplication. If you allocate on the stack then you'd use:
MyClass c(param);
However, if you want to create on the heap you need:
MyClass* c=new MyClass(param);
So you've had to duplicate the MyClass, but the RHS already forces the variable to be a MyClass pointer, so you can just use this instead:
auto c=new MyClass(param);
If you want to declare it as a unique_ptr then previously you would need:
unique_ptr<MyClass> c=make_unique<MyClass>(param);
which can be abbreviated to:
auto c=make_unique<MyClass>(param);
In C++, auto keyword provides a way of type deduction mechanism. For example,
auto i = expressions;
auto keyword tells the compiler to determine the type of variable i from the expression on the right side of the assignment operator.
Therefore if the value of expressions is double, then variable i will be double. Or, if the value of expressions is bool, then variable i will be bool.
so, let's learn type inference first which is basically refers to automatic deduction of the data type of an expression in a programming language.
before C++ 11 all the variables in c++ have to explicitly declare but after the release of c++ 11, the compiler itself deduces the type of the variable at runtime.
we can use it for variables and even in the case of function return types.
but, it's suggested to avoid using auto in function return type.
Given a class definition in C++
class A
{
public:
//methods definition
....
private:
int i;
char *str;
....
}
Is it possible to calculate the offset of a class member at compile time using C++ template meta-programming? The class is not POD, and can have virtual methods, primitive and object data member.
Based on Matthieu M.'s answer but shorter and with no macros:
template<typename T, typename U> constexpr size_t offsetOf(U T::*member)
{
return (char*)&((T*)nullptr->*member) - (char*)nullptr;
}
And it's called like this:
struct X { int a, b, c, d; }
std::cout << "offset of c in X == " << offsetOf(&X::c);
Edit:
Jason Rice is correct. This will not produce an actual constant expression in C++11. It doesn't look possible given the restrictions in http://en.cppreference.com/w/cpp/language/constant_expression -- in particular no pointer difference and reinterpret_castcan be in a constant expression.
Well... in C++11, you actually can compute such offsets right with regular C++ facilities (ie, without delegating to a particular compiler intrinsic).
In action at liveworkspace:
template <typename T, typename U>
constexpr int func(T const& t, U T::* a) {
return (char const*)&t - (char const*)&(t.*a);
}
However this relies on t being a reference to a constexpr instance here, which might not be applicable to all classes. It does not forbid T from having a virtual method though, nor even a constructor, as long as it is a constexpr constructor.
Still, this is quite a hindrance. In unevaluated contexts we could actually use std::declval<T>() to simulate having an object; while having none. This poses no specific requirements on the constructor of an object, therefore. On the other hand, the values we can extract from such context are few... and they do pose issues with current compilers, too... Well, let's fake it!
In action at liveworkspace:
template <typename T, typename U>
constexpr size_t offsetof_impl(T const* t, U T::* a) {
return (char const*)t - (char const*)&(t->*a) >= 0 ?
(char const*)t - (char const*)&(t->*a) :
(char const*)&(t->*a) - (char const*)t;
}
#define offsetof(Type_, Attr_) \
offsetof_impl((Type_ const*)nullptr, &Type_::Attr_)
The only issue I foresee is with virtual inheritance, because of its runtime placement of the base object. I would be glad to be presented with other defects, if there are.
No, not in general.
The offsetof macro exists for POD (plain old data) structs, and it may be extended slightly with C++0x to standard layout structs (or other similar slight extensions). So for those restricted cases, you have a solution.
C++ offers a lot of freedom to compiler writers. I don't know of any clause that would prevent some classes from having variable offsets to members of the class -- however, I'm not sure why a compiler would do that either. ;)
Now, one approach to keep your code standards compliant, yet still have offsets, would be to stick your data into a POD (or some C++0x extension) sub-struct, on which offsetof will work, then work on that sub-struct instead of on the entire class. Or you could surrender standards compliance. The offset of your struct within your class wouldn't be known, but the offset of the member within the struct would be.
An important question to ask is "why do I want this, and do I really have a good reason"?
In the 1996 book "Inside the C++ Object Model", written by Stanley B. Lippman, one of the original C++ designer's, makes reference to Pointer-to-Member Functions in Chapter 4.4
the value returned from taking the address of a nonstatic data member is the byte value of the member's position in the class layout (plus 1). One can think of it as an incomplete value. It needs to be bound to the address of a class object before an actual instance of the member can be accessed.
While I vaguely recall that +1 from somewhere in some previous life, I've never seen or made use of this syntax before.
class t
{
public:
int i;
int j;
};
int (t::*pmf)() = &t::i;
At least according to the description, this seems to be a cool way to get "almost" the offset.
But It doesn't seem to work anymore, at least in GCC. I get a
Cannot initialize a variable of type 'int (t::*) with an rvalue of type "int t:: *'
Does anybody have any history behind what is going on here? Is something like this still possible?
Problem with the web -- obsolete books never die...
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.
While reading Wikipedia's page on decltype, I was curious about the statement,
Its [decltype's] primary intended use is in generic
programming, where it is often
difficult, or even impossible, to name
types that depend on template
parameters.
While I can understand the difficulty part of that statement, what is an example where there is a need to name a type that cannot be named under C++03?
EDIT: My point is that since everything in C++ has a declaration of types. Why would there ever be a case where it is impossible to name a type? Furthermore, aren't trait classes designed to yield type informations? Could trait classes be an alternative to decltype?
The wikipedia page you link has a perfect example:
int& foo(int& i);
float foo(float& f);
template <class T> auto transparent_forwarder(T& t) −> decltype(foo(t)) {
return foo(t);
}
Note that foo(int&) returns int& (a reference type) while foo(float&) returns float (a nonreference type). Without decltype, it's impossible within the template to specify a type which represents "the return type of the function foo which takes an argument t of type T".
In this example, it's not a particular concrete type which is impossible to express -- either int& or float are individually expressible -- but a higher level generic class of types.
EDIT: and to answer your comment to another answer, this example is inexpressible in C++03. You cannot have a function template which will wrap any function T1 foo(T2) and match both argument and return type of the wrapped function.
There are types in C++0x (and in C++03, but less often) that cannot be named explicitly, such as the type decltype(f) after the declaration auto f = [](int x) -> int {return x;};. You would need to typedef that decltype result to something to get a name at all. Traits classes can be used for determining return types, but they are messy, and the user needs to duplicate all of their function overloads with traits class overloads; that is difficult to do correctly for cases such as functions applying (through implicit conversion of pointers) to all subclasses of a given base class.
As you pointed out, the type if it exist is known by the compiler, otherwise it wouldn't exist. However, it is not always readily or even accessible to the programmer in C++03.
N1607 mention the following in its conclusion:
In C++2003, it is not possible to
express the return type of a function
template in all cases. Furthermore,
expressions involving calls to
function templates commonly have very
complicated types, which are
practically impossible to write by
hand
The question is how do we access this type as a programmer. This is not always a trivial process, often impracticable. It is increasingly complex when you have an expression for which you desire to know the result type. You would have to break it into pieces in order to figure the result types. It is not possible to simplify this process using templates (not without evaluating the expression anyhow). Breaking the expression will be error-prone, tedious and a nightmare to maintain. Think of this code:
x.g()[b.a(e)]->f();
With C++98/TR1, it is often infeasible to name types that depend on template parameters. Traits offers us so much information, but eventually decltype is a much cleaner solution to many problems. A lot of the information available to you when meta programming is only available because libraries, such as boost or loki, use several tricks hidden in the dark corners of the C++98 language.
Of course this is irrelevant to your question but I believe that it is worthy to mention that C++98 compilers already have mechanics to know these types. This is exactly what sizeof offers, except that it returns you a size. decltype reuse some of this functionality and solves these problems with greater elegance.
As for a different (academic) example:
struct Foo
{
struct
{
int x;
} bar;
};
template<typename T>
void
f(const T& t)
{
// C++03, How can I name the type of T::bar ?
// C++0x
// decltype(t.bar) cpy;
// Do stuff with our local cpy
}
int
main()
{
f(Foo());
}