Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #6083
| From | Victor Bazarov <v.bazarov@comcast.invalid> |
|---|---|
| Newsgroups | comp.lang.c++ |
| Subject | Re: Casting template argument |
| Date | 2011-06-02 10:17 -0400 |
| Organization | A noiseless patient Spider |
| Message-ID | <is8629$ook$1@dont-email.me> (permalink) |
| References | <4de78326$0$6554$9b4e6d93@newsspool4.arcor-online.net> |
On 6/2/2011 8:33 AM, Marcel Müller wrote:
> I want to cast a template argument. Unfortunately gcc creates an error
> as if the cast has never been there. Is this not allowed generally?
Yep. Not allowed.
The requirement is that a non-type template argument is expected to be
the address of a function, "expressed as & id-expression where the & is
optional if the name refers to a function or array". That means that
the "explicit type conversion expressions" are *not allowed*. Bummer.
What you perhaps need is to supply your pointer expression (by just
using the name of the function) and hope that the compiler performs the
necessary conversion itself. Standard, [temp.arg.nontype]/5 explains
what conversions are applied:
<<
The following conversions are performed on each expression used as a
non-type template-argument. If a non-type template-argument cannot be
converted to the type of the corresponding template-parameter then
the program is ill-formed.
— for a non-type template-parameter of integral or enumeration type,
integral promotions (4.5) and integral conversions (4.7) are applied.
— for a non-type template-parameter of type pointer to object,
qualification conversions (4.4) and the array-to-pointer conversion
(4.2) are applied. [Note: In particular, neither the null pointer
conversion (4.10) nor the derived-to-base conversion (4.10) are applied.
Although 0 is a valid template-argument for a non-type
template-parameter of integral type, it is not a valid template-argument
for a non-type template-parameter of pointer type. ]
— For a non-type template-parameter of type reference to object, no
conversions apply. The type referred to by the reference may be more
cv-qualified than the (otherwise identical) type of the
templateargument. The template-parameter is bound directly to the
template-argument, which must be an lvalue.
— For a non-type template-parameter of type pointer to function, only
the function-to-pointer conversion (4.3) is applied. If the
template-argument represents a set of overloaded functions (or a pointer
to such), the matching function is selected from the set (13.4).
— For a non-type template-parameter of type reference to function, no
conversions apply. If the template-argument represents a set of
overloaded functions, the matching function is selected from the
set (13.4).
— For a non-type template-parameter of type pointer to member function,
no conversions apply. If the template-argument represents a set of
overloaded member functions, the matching member function is
selected from the set (13.4).
— For a non-type template-parameter of type pointer to data member,
qualification conversions (4.4) are applied.>>
Your case seems to fall into the fourth bullet point. What you will
likely to encounter is another compiler error since the function is not
of the type expected by the compiler. You need a wrapper function.
> -----
> #include <string.h>
>
> // Sorted vector of T with the key type K using the comparer C.
> template <class T, class K, int (*C)(const T* e, const K* k)>
> class sorted_vector
> {public:
> // Find an element by it's key.
> // The function will return NULL if no such element is in the container.
> T* find(const K* key) const;
> // Ensure an element with a particular key.
> // This will either return a reference to a pointer to an existing object
> // which equals to key or a reference to a NULL pointer which is
> // created at the location in the container where a new object with key
> // should be inserted.
> T*& get(const K* key);
> // Erase the element which equals key and return the removed pointer.
> // If no such element exists the function returns NULL.
> T* erase(const K* key);
> };
>
> // data structure, POD
> struct data
> { char Key[10];
> char Value[10];
> };
>
> // Works
> int (*const comparer)(const data*, const char*)
> = (int (*)(const data*, const char*))&strcmp;
"Works" - what do you mean? You have a C-style cast here. Whether it
achieves what you expect is not known until you actually try invoking
that function using that 'comparer' pointer.
> // does not work, see below
> typedef sorted_vector<data, char,
> (int (*)(const data*, const char*))&strcmp> stringmap;
Have you tried without the cast? What do you get?
> -----
>
> test6.cpp:34: error: could not convert template argument `strcmp' to `int
> (*)(const data*, const char*)'
>
>
> Of cource, strcmp does not compare against objects of type data, but
> since data is a POD type the equivalence of const data* and const char*
> should not raise serious problems, and a helper function should be
> superfluous.
<shrug> You're trying to cheat the system by using the C-style cast.
That's *usually* an invitation for UB.
V
--
I do not respond to top-posted replies, please don't ask
Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Casting template argument Marcel Müller <news.5.maazl@spamgourmet.org> - 2011-06-02 14:33 +0200
Re: Casting template argument Victor Bazarov <v.bazarov@comcast.invalid> - 2011-06-02 10:17 -0400
Re: Casting template argument Marcel Müller <news.5.maazl@spamgourmet.org> - 2011-06-02 22:10 +0200
Re: Casting template argument Pete Becker <pete@versatilecoding.com> - 2011-06-02 10:21 -1000
Re: Casting template argument Marcel Müller <news.5.maazl@spamgourmet.org> - 2011-06-02 22:34 +0200
Re: Casting template argument Pete Becker <pete@versatilecoding.com> - 2011-06-02 10:40 -1000
csiph-web