Templates: how to throw a compiler error?

R

Rui Maciel

Let's say we have a template class which takes non-type arguments. Is it possible to throw a
compiler error presenting the user with an informative error message if the user happens to pass a
specific argument which is considered invalid in the class' design?


Thanks in advance,
Rui Maciel
 
A

Alf P. Steinbach /Usenet

* Rui Maciel, on 05.10.2010 16:37:
Let's say we have a template class which takes non-type arguments. Is
it possible to throw a compiler error presenting the user with an
informative error message if the user happens to pass a specific argument
which is considered invalid in the class' design?

Yes.


Cheers & hth.,

- Alf
 
V

Victor Bazarov

Let's say we have a template class which takes non-type arguments. Is it possible to throw a
compiler error presenting the user with an informative error message if the user happens to pass a
specific argument which is considered invalid in the class' design?

Some tricks can be played, but since there is no "custom error message"
that one can push into the compiler, the possibilities are limited.
Example can be an attempt to define an array of a zero or negative size,
the name of which you can use to indicate to the user that the value is
outside of bounds...

// let's say you want to limit the parameter to the range [100,200]
// (inclusive)

template<int a, int b> struct verify_smaller {
enum first_arg_must_be_smaller_than_second { OK = (b > a) };
};

template<int a, int b> struct verify_greater {
enum first_arg_must_be_greater_than_second { OK = (a > b) };
};

template<int a, int b> struct verify_nosmaller {
enum first_arg_must_be_smaller_than_second { OK = (a >= b) };
};

template<int a, int b> struct verify_nogreater {
enum first_arg_must_be_nogreater_than_second { OK = (a <= b) };
};

template<int i, int low, int high> struct verify_in_range
{
enum { OK = (verify_smaller<low,high>::OK
&& verify_nosmaller<i, low>::OK
&& verify_nogreater<i, high>::OK) };
};

template<int i> class mytemplate
{
char (& requirements())[verify_in_range<i, 100, 200>::OK];
};

int main()
{
mytemplate<150> ok_One;
mytemplate<100> ok_Two;
mytemplate<200> ok_Three;
mytemplate<0> not_OK; // produces error
mytemplate<1000> not_OK2; // produces error
}

I am sure you can come up with a simpler way.

V
 
S

Stefan van Kessel

Let's say we have a template class which takes non-type arguments. Is it possible to throw a
compiler error presenting the user with an informative error message if the user happens to pass a
specific argument which is considered invalid in the class' design?

In C++0x there will be static_assert so you can do something like:

template <int N>
struct Foo
{
static_assert(N!=42, "I don't know the question");
};

which when Foo<42> is instantiated will create an error message
something like:

1>main.cpp(4): error C2338: I don't know the question
1> main.cpp(9) : see reference to class template instantiation
'Foo<N>' being compiled
1> with
1> [
1> N=42
1> ]

or

main.cpp: In instantiation of 'Foo<42>':
main.cpp:9: instantiated from here
main.cpp:4: error: static assertion failed: "I don\'t know the question"


Gcc supports it since 4.3 and msvc10 does, too. If you need a more
portable solution you can also use boost.static_assert:

#include <boost/static_assert.hpp>
template <int N>
struct Foo
{
BOOST_STATIC_ASSERT(N!=42);
};

For more complex requirements there is also boost.concept_check.

There are of course also numerous ways to force a compile time error
yourself like enum{ test = N/(42-N) }; or a specialization for certain
arguments that causes an error upon instantiation, for example like:

template <int N>
struct assert_not_42
{
typedef char success;
};

template <>
struct assert_not_42<42>
{
};

template <int N>
struct Foo
{
typedef typename assert_not_42<N>::success check;
};

which might, when Foo is instantiated with 42, cause an error like:

1>main.cpp(18): error C2039: 'success' : is not a member of
'assert_not_42<42>'
1> main.cpp(12) : see declaration of 'assert_not_42<42>'
1> main.cpp(23) : see reference to class template instantiation
'Foo<N>' being compiled
1> with
1> [
1> N=42
1> ]

Have a nice day,
Stefan
 
J

Jeff Flinn

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top