Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #6083

Re: Casting template argument

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>

Show all headers | View raw


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


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