473,851 Members | 2,021 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

template metaprogramming syntax

Hello. If I declare the following:

template<int a, int b, int SomeArray[]>
class DoSomething{

public:
..
..
..

I have no problems, and the compiler is quite happy, and my template
function works as expected. But I want to add in an array for my
template to act on. I change the first line to:

template<int MIDPOINT, int Key, int ArrayToSearch[]>

but I get the following error:
error: provided for 'template<int a, int b, int * SomeArrayclass
DoSomething'

Why do I get this error when I attempt to pass in an array? What can
I do to get rid of this error? Is there a correct way to pass arrays
around inside a template?

Thanks!
Oct 14 '08 #1
12 3375
On Mon, 13 Oct 2008 23:12:53 -0700 (PDT),
"no************ *********@yahoo .com"
<no************ *********@yahoo .comwrote:
>Why do I get this error when I attempt to pass in an array? What can
I do to get rid of this error? Is there a correct way to pass arrays
around inside a template?
You haven't really posted enough information here, and what you have
posted is confusing. For example...
>template<int a, int b, int SomeArray[]>
>template<int MIDPOINT, int Key, int ArrayToSearch[]>
These two template lines are identical, other than the parameter
names. The compiler shouldn't care which you use.

I will take a guess, though.

Basically, an array is a run-time data type. Trying to use arrays for
metaprogramming seems unlikely to work.

Using an array as a template parameter is intended for cases where a
generic algorithm is to be applied to a single application-specific
array, which must be global or static. It's normally a bad idea -
trying to avoid run-time parameter passing can be a recipe for
code-bloat.

The "right" way to do metaprogramming (if there is such a thing) is
using recursive structures such as linked lists. The items in your
lists will be C++ template classes, recursively defined so that each
template class contains a variation of itself as a member (probably a
typedef). Specialisation will be used to terminate the list (ie define
a class that doesn't have a recursive child). The values will often be
member types, member enumerates, or const static member fields.

With that kind of structure, you're far more likely to be using linear
searches than binary searches, though binary trees are certainly
possible. Binary searches may be needed, but over value search-spaces,
not over "data" structures. An example where a binary search makes
sense for metaprogramming is the classic integer square root.

My advice - play with Scheme, Haskell or Objective Caml for a bit,
then (if you must) come back to template metaprogramming when you're
used to handling lists in a recursive functional way. Using a
functional language is much easier as there's far less code overhead
for the relevant concepts, and if you're used to an imperitive
approach, you may need to do a paradigm shift.

BTW - I'm not against metaprogramming . I'm just against
metaprogramming in C++. The current template facilities aren't
designed for it, and aren't really up to doing the job. Template
metaprogramming also imposes a completely different approach for
compile-time code than for run-time code, as you appear to be
discovering. If you can't use run-time code or relatively simple
template methods (policies and mixin layers are OK, to a point), my
view is that you should write a code generator or domain-specific
language. That or work in Objective Caml, which supposedly allows
metaprogramming in the same style as the run-time programming, though
I personally never got past the basic of the language.

Oct 14 '08 #2
On Oct 14, 8:12 am, "nooneinparticu lar314...@yahoo .com"
<nooneinparticu lar314...@yahoo .comwrote:
Hello. If I declare the following:
template<int a, int b, int SomeArray[]>
class DoSomething{
public:
.
.
.
I have no problems, and the compiler is quite happy, and my
template function works as expected. But I want to add in an
array for my template to act on. I change the first line to:
template<int MIDPOINT, int Key, int ArrayToSearch[]>
but I get the following error:
error: provided for 'template<int a, int b, int * SomeArrayclass
DoSomething'
Why do I get this error when I attempt to pass in an array?
What can I do to get rid of this error? Is there a correct
way to pass arrays around inside a template?
The only allowable types for a template non-type parameter are
integral or enumeration types, pointers to objects or to
functions, references to objects or to functions or pointers to
members. An array is none of these.

An array is an object, however, and you can use either a pointer
to an array or a reference to an array, e.g.:

template<int MIDPOINT, int Key, int (&ArrayToSearch )[]>

Note that you're likely to get into trouble here with the
dimensions, however.

Alternatively, you can use the old C hack, declare the argument
int*, and pass it the address of the first element.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 14 '08 #3
Stephen Horne wrote:
...
BTW - I'm not against metaprogramming . I'm just against
metaprogramming in C++. The current template facilities aren't
designed for it, and aren't really up to doing the job. Template
metaprogramming also imposes a completely different approach for
compile-time code than for run-time code, as you appear to be
discovering. If you can't use run-time code or relatively simple
template methods (policies and mixin layers are OK, to a point), my
view is that you should write a code generator or domain-specific
language. That or work in Objective Caml, which supposedly allows
metaprogramming in the same style as the run-time programming, though
I personally never got past the basic of the language.
C++ TMP is the greatest thing since sliced bread. In-language
metaprogramming is at least very convenient, and can drastically
increase productivity. I have yet to see a stand-alone C++ code
generator that produces anything human-readable, much less maintainable.
Even the standard preprocessor has some pretty serious drawbacks.

The popular compilers may not have been "up to doing the job" ten years
ago, they are now. The extreme differences between compile-time and
run-time syntax you mentioned can be annoying, but (1) the new standard
greatly improves the situation with the decltype, constexpr, and auto
keywords, and (2) syntax that makes it obvious which code runs at
compile-time isn't necessarily evil.
Oct 14 '08 #4
On Oct 14, 9:40 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
On Mon, 13 Oct 2008 23:12:53 -0700 (PDT),
"nooneinparticu lar314...@yahoo .com"
<nooneinparticu lar314...@yahoo .comwrote:
Why do I get this error when I attempt to pass in an array?
What can I do to get rid of this error? Is there a correct
way to pass arrays around inside a template?
You haven't really posted enough information here, and what
you have posted is confusing. For example...
template<int a, int b, int SomeArray[]>
template<int MIDPOINT, int Key, int ArrayToSearch[]>
These two template lines are identical, other than the
parameter names. The compiler shouldn't care which you use.
I will take a guess, though.
Basically, an array is a run-time data type. Trying to use
arrays for metaprogramming seems unlikely to work.
The first statement is false (or you meant something different
than what you said). An array is a type known to the compiler,
and it's possible to instantiate templates with references to
arrays, etc. Accessing an array is never a constant expression,
however, even if the array is const, it's initializer is
visible, and the index is a constant integral expression. Which
means that you can't use array elements (even const) as template
arguments. (Since his array type wasn't const, I doubt that he
was trying to do metaprogramming . Even if his choice of names
is very suggestive of a compile time binary search.)
Using an array as a template parameter is intended for cases
where a generic algorithm is to be applied to a single
application-specific array, which must be global or static.
It's normally a bad idea - trying to avoid run-time parameter
passing can be a recipe for code-bloat.
It depends on what you're doing. Things like:

template< typename T, std::size_t N >
T*
end( T (&array)[ N ] )
{
return array + N ;
}

are a standard part of everyone's tool kit. The compiler can
deduce the number of elements in the array as part of template
argument deduction, and where counting is involved, I trust the
compiler more than I do myself.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Oct 14 '08 #5
On Tue, 14 Oct 2008 02:58:18 -0700 (PDT), James Kanze
<ja*********@gm ail.comwrote:
>On Oct 14, 9:40 am, Stephen Horne <sh006d3...@blu eyonder.co.ukwr ote:
>Basically, an array is a run-time data type. Trying to use
arrays for metaprogramming seems unlikely to work.

The first statement is false (or you meant something different
than what you said). An array is a type known to the compiler,
and it's possible to instantiate templates with references to
arrays, etc.
Very pendantically, I meant something different to what I said...
Accessing an array is never a constant expression,
however, even if the array is const, it's initializer is
visible, and the index is a constant integral expression.
And that is what I didn't know for certain but suspected.

In practice, this means that arrays are not compile-time data types.
They can be referred to at compile time and their types can be
manipulated, but they can't be accessed or updated which is what
arrays are basically for.
>Using an array as a template parameter is intended for cases
where a generic algorithm is to be applied to a single
application-specific array, which must be global or static.
It's normally a bad idea - trying to avoid run-time parameter
passing can be a recipe for code-bloat.

It depends on what you're doing. Things like:

template< typename T, std::size_t N >
T*
end( T (&array)[ N ] )
{
return array + N ;
}

are a standard part of everyone's tool kit.
The array isn't a template parameter in this case - it's a method
parameter which is used to infer the template parameters (non-array)
types. Not the same thing, and not what I'd call template
metaprogramming with arrays. It's doing pattern-matching, yes, but
it's doing what templates were designed to do from the start.
The compiler can
deduce the number of elements in the array as part of template
argument deduction, and where counting is involved, I trust the
compiler more than I do myself.
Agreed.

That said, with trivial library tools, I tend to think they obscure
more than they reveal. The names tend not to express *precisely* what
the code does, and you can end up in the perverse situation where the
manually written code is more readable and maintainable, and far less
error prone, than the library call.

Not in the above case, since "end" is so heavily used and it's meaning
relative to containers generally is familiar to any competent C++
programmer.

Oct 14 '08 #6
Stephen Horne wrote:
On Tue, 14 Oct 2008 02:58:18 -0700 (PDT), James Kanze
<ja*********@gm ail.comwrote:

[...]
>It depends on what you're doing. Things like:

template< typename T, std::size_t N >
T*
end( T (&array)[ N ] )
{
return array + N ;
}

are a standard part of everyone's tool kit.

The array isn't a template parameter in this case - it's a method
parameter which is used to infer the template parameters (non-array)
types. Not the same thing, and not what I'd call template
metaprogramming with arrays. It's doing pattern-matching, yes, but
it's doing what templates were designed to do from the start.
You're probably mostly on your own when you don't consider
this being TMP. Nevertheless, here's a pure compile-time
construct for getting an array's number of elements:
namespace detail {
template <typename T, const std::size_t N>
const char ( &static_array_s ize_(T const (&)[N]) ) [N];
}
#define static_array_si ze(a) sizeof(detail:: static_array_si ze_(a))
Would you consider this TMP?
> The compiler can
deduce the number of elements in the array as part of template
argument deduction, and where counting is involved, I trust the
compiler more than I do myself.

Agreed.

That said, with trivial library tools, I tend to think they obscure
more than they reveal. The names tend not to express *precisely* what
the code does, and you can end up in the perverse situation where the
manually written code is more readable and maintainable, and far less
error prone, than the library call.
This not only depends on the tool, but also on the alternatives.
Too often for my taste, in code like 'sizeof(arr)', 'arr' turned
out to be a pointer instead of an array. Horrendous compile-time
error messages suddenly seem not all that bad compared to what
happens at run-time.
For a while, I've worked on projects where, if only 0.1% of the
customers had called for support, the company we worked for would
have gone bankrupt immediately. From that POV, almost any compile-
time error message horror is acceptable if it prevents only one
bug from triggering run-time.

Schobi
Oct 15 '08 #7
On Wed, 15 Oct 2008 13:36:18 +0200, Hendrik Schober <sp******@gmx.d e>
wrote:
You're probably mostly on your own when you don't consider
this being TMP.
The point is that templates were designed to do a job which they do
well. Then they were pushed to do more. The term "template
metaprogramming " wasn't even coined until some time after templates
were being routinely used.

Therefore, I'm taking the term "metaprogrammin g" in a subjective way,
not referring to objective language features, but to the way in which
they are used. Which I think is how most people understand the term.

And I stick by the opinion - until the language is made more robust
WRT metaprogramming , I don't want to see every Tom, Dick and Harry
shoving metaprogramming code everywhere. What's valid as an experiment
or for people who really know what they're doing (and really need to
do it) may still need to be treated with caution.
Would you consider this TMP?
Probably not, but there's no hard line. If "template metaprogramming "
means something other than "template", that meaning must be somewhat
subjective.

*Real* TMP, to me, at the very least uses multiple templates with
interacting specialisation trickery, and I'm only sure it really
qualifies when you start seeing recursive definitions - things like
those compile-time square-root and trig functions are about the
simplest definitely-qualifies stuff I'll accept as metaprogramming .
It's like I don't consider people to have done real imperative
programming just because they can type an expression into Python.
This not only depends on the tool, but also on the alternatives.
Too often for my taste, in code like 'sizeof(arr)', 'arr' turned
out to be a pointer instead of an array. Horrendous compile-time
error messages suddenly seem not all that bad compared to what
happens at run-time.
Agreed. TMP or not, trivial or not, any tool may or may not be a good
thing. It requires a pragmatic - rather than dogmatic - attitude to
figure out which is which.

"The libraries are there therefore use them" doesn't work for me. I
use what I think will work best in the circumstances.

OTOH, it's clear than in some respects my knowledge of what the
library guarantees is dated (or maybe was always wrong), so some of my
decisions based on that will have been wrong. Oh well.

Oct 15 '08 #8
Stephen Horne wrote:
On Wed, 15 Oct 2008 13:36:18 +0200, Hendrik Schober <sp******@gmx.d e>
wrote:
> You're probably mostly on your own when you don't consider
this being TMP.

The point is that templates were designed to do a job which they do
well. Then they were pushed to do more. The term "template
metaprogramming " wasn't even coined until some time after templates
were being routinely used.
I know TMP was an accidental discovery and I know that that's
the main reason for meta programming being so hard to do. Still,
every bug showing up during compilation won't hit a customers.
And that's a very important argument pro TMP.
Therefore, I'm taking the term "metaprogrammin g" in a subjective way,
not referring to objective language features, but to the way in which
they are used. Which I think is how most people understand the term.
I don't know. I always thought people understand it the way
Scott Meyers described it in "Effective C++". Essentially:
TMP is writing programs that execute inside the compiler
during compilation and result in ordinary C++ programs which
are then regularly compiled.
Of course, that leaves room to interpretation as to whether
some specific code snipped is TMP or not.
And I stick by the opinion - until the language is made more robust
WRT metaprogramming , I don't want to see every Tom, Dick and Harry
shoving metaprogramming code everywhere. What's valid as an experiment
or for people who really know what they're doing (and really need to
do it) may still need to be treated with caution.
If Tom, Dick, and Harry manage to write more reliable software
through using TMP, I'm fine with them doing so.
[...]
Schobi
Oct 15 '08 #9
On Wed, 15 Oct 2008 17:19:12 +0200, Hendrik Schober <sp******@gmx.d e>
wrote:
I know TMP was an accidental discovery and I know that that's
the main reason for meta programming being so hard to do. Still,
every bug showing up during compilation won't hit a customers.
And that's a very important argument pro TMP.
Catching bugs at compile-time is a big argument pro static checking,
certainly. It is, however, perfectly possible for TMP code to have
bugs that cause it to generate incorrect run-time code without any
errors or warnings. I've had that happen with (what I thought was)
reasonably simple policy-based code, which I don't even consider to be
metaprogramming .

Any code can have untested cases with stupid typos, out-by-one errors,
or whatever, and if that compile-time error results in a run-time
error in some relatively unusual run-time special case, are you
certain your unit tests caught it? Unit tests that were designed for a
different white box, because one of your template parameters changed,
restructuring that white box in some subtle way?

The real issue is whether you can read, understand, maintain, test,
and generally have confidence in the code. Templates are just
templates. I only add the "metaprogrammin g" when I'm scared of it, I
guess.
I don't know. I always thought people understand it the way
Scott Meyers described it in "Effective C++". Essentially:
TMP is writing programs that execute inside the compiler
during compilation and result in ordinary C++ programs which
are then regularly compiled.
I read some papers by Todd whatshisname, never read Effective C++. At
least I don't think I did. It's possible I read some in a library once
- could be where I got the word 'policy' from.
>And I stick by the opinion - until the language is made more robust
WRT metaprogramming , I don't want to see every Tom, Dick and Harry
shoving metaprogramming code everywhere. What's valid as an experiment
or for people who really know what they're doing (and really need to
do it) may still need to be treated with caution.

If Tom, Dick, and Harry manage to write more reliable software
through using TMP, I'm fine with them doing so.
But if they don't know what they're doing, it's not reliable. And even
if you catch the error at compile time, a month past deadline because
a template parameter changed and caused a thousand cryptic error
messages and no-one could understand or maintain the TMP stuff because
the guy who wrote it left a year ago...

TMP is just compile-time programming. People have been doing it in
Lisp for decades, with a language designed for the job - and they've
certainly managed to release some buggy code in that time.

TMP may be more of a Haskell/Prolog mix rather than Lisp, but the
point stands. It's not magic bug spray.

Oct 15 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2167
by: Dave | last post by:
Would people agree with the statement that to a large degree, using template metaprogramming techniques turns a C++ compiler into a C++ interpreter (but just for the metaprogrammed portions of the code)? It's not a perfect analogy, but it seems to be a reasonable statement...
5
1728
by: Mohammad | last post by:
Hi, Is it possible to disable a method of a template class depending on the typename at compile time? thanks!
5
2166
by: Steve | last post by:
Hi, Does C++ allow the programmer to declare a template with in a template so that a generic function can instantiate the embedded template? For example, could code such as this exist: template< class T<int N> > int func() { int the_n = N;
5
3374
by: Mark Stijnman | last post by:
I am trying to teach myself template metaprogramming and I have been trying to create lists of related types. I am however stuck when I want to make a template that gives me the last type in a list. I started by using a linked list of types with templates like: struct MyClass1 {}; struct MyClass2 {}; struct MyClass3 {}; struct NullType {};
7
3584
by: Joe | last post by:
Hi, I found a concept named template metaprogramming that can be used in C+ + code at compile-time. I am a beginner at C++. But I am a programmer on the .NET platform. Do you know if template metaprogramming is supported in C# (.NET)? For reference I found it: http://en.wikipedia.org/wiki/Template_metaprogramming. Thanks to all.
4
1909
by: Alan Woodland | last post by:
I've been trying out more template metaprogramming ideas with typelists (mostly for personal learning, I'm aware boost most probably provides this facility already), and I've run into this small problem here. Comeau online (without C++0x, in strict mode) accepts this example pasted here, (apologies for the length of it). Unfortunately G++ (3.4, 4.1, 4.2) doesn't, and complains about index_find being private. The exact error it gives is:...
5
3625
by: iapx86 | last post by:
My parser project calls for a computed goto (see code below). The C preprocessor delivers the desired result, but is ugly. Template metaprogramming delivers results I do not understand. Can anyone explain why loop unrolling doesn't play well with templates? Or better, can someone submit a code fragment to get desired results? Here are the command-lines I use to generate code: "g++ -DTEMPLATE=0 -o gotofun0 gotofun.cpp" works exactly as...
6
391
by: Gaijinco | last post by:
I'm trying to do a template class Node. My node.hpp is: #ifndef _NODE_HPP_ #define _NODE_HPP_ namespace com { namespace mnya { namespace carlos { template <typename T>
4
254
by: nooneinparticular314159 | last post by:
I'm trying to understand template metaprogramming syntax. It's been years since I've touched C++, so this may actually be a C++ syntax issue (although it seems that the language has changed somewhat.) The following example comes from http://www.codeproject.com/KB/cpp/crc_meta.aspx template< int i > class FACTOR{ public: enum {RESULT = i * FACTOR<I-1>::RESULT};
0
9897
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11019
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10728
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10356
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9506
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
7073
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5933
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
4143
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3179
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.