Howard Hinnant wrote in ge0.nyroc.rr.com:
You can also restrict T for the purpose of guiding overload resolution
(though it is far from clear that that is what the OP needed). Search
for "restrict_to" and "enable_if".
It actually doesn't do a bad job at all:
g++ -O2 -W -Wall -pedantic -ansi -o test-gcc.exe test.cpp
compiling:
test.cpp: In function `int main()':
test.cpp:76: no matching function for call to `SQ(A)'
cl /W3 /Za /Zc:forScope,wchar_t /GR /O2 /TP /EHs test.cpp
compiling:
test.cpp
test.cpp:76: error C2893: Failed to specialize function template
'restrict_to<T,
can_multiply<T>::value>::type SQ(const T &)'
With the following template arguments:
'A'
bccx -O2 -w-8027 -otest-cbx.exe test.cpp
compiling:
Borland C++ 6.0 Preview for Win32 Copyright (c) 1993, 2003 Borland
Error test.cpp 76: no instance of function template "SQ" matches the
argument list
A lot of typing for a clean error message though:
#include <iostream>
#include <ostream>
#include <iomanip>
namespace detail
{
struct unique {};
typedef char False;
typedef char (&True)[2];
template < typename T >
unique operator * ( T const &, T const & );
template < typename X >
False is_unique( X const & );
True is_unique( unique );
template < typename T > T const &c_ref();
/* Simplistic implementation, doesn't check wether
T * T is convertable to T
*/
template < typename T > struct can_multiply
{
static bool const value =
sizeof( is_unique( c_ref< T >() * c_ref< T >() ) )
==
sizeof( False )
;
};
} /* detail:: */
template < typename T >
struct can_multiply : detail::can_multiply< T >
{
};
template < typename T, bool False > struct restrict_to
{
};
template < typename T> struct restrict_to< T, true >
{
typedef T type;
};
template < typename T >
typename restrict_to< T, can_multiply< T >::value >::type
SQ( T const &a )
{
return a * a;
}
struct A {};
#define FAIL
int main()
{
using namespace std;
cerr << boolalpha;
cerr << can_multiply< int >::value << '\n';
cerr << can_multiply< A >::value << '\n';
cerr << SQ( 3 ) << '\n';
#if defined( FAIL )
cerr << SQ ( A() ) << '\n'; // line 76
#endif
}
Rob.