f



function overload with array types and pointer types

{ Please limit your text to fit within 80 columns, preferably around 70,
  so that readers don't have to scroll horizontally to read each line.
  This article has been reformatted manually by the moderator. -mod }


I have the following code.

----------------- BEGIN ----------------
#include <cstddef>
#include <type_traits>

template <typename T0, typename T1>
typename std::enable_if<sizeof(T0)==sizeof(T1)>::type
inline f (T0 const* const t0, T1 const* const t1)
{
 // do something to *t0 and *t1
}

template <typename T0, typename T1, size_t N0, size_t N1>
typename std::enable_if<sizeof(T0)==sizeof(T1) && N0==N1>::type
inline f (T0 const (&t0) [N0], T1 const (&t1) [N1])
{
 for (size_t i = 0; i != N0; ++i)
 {
  // do something to t0[i] and t1[i]
 }
}

int main ()
{
 size_t const a [5] {0};
 size_t const b [5] {0};
 f(a,b);
}
-----------------  END  ----------------
It was accepted by g++-4.7.0 but rejected by 4.8.0 and all other
compilers I have tested. These facts led me to assume the code should be
rejected according to the standard.

I realize that the array-to-pointer conversion has Exact Match rank
according to Table 12 from 13.3.3.1.1. However, the match to the second
overload is an identity conversion and 13.3.3.2/3 bullet one reads:

"S1 is a proper subsequence of S2 (comparing the conversion sequences in
the canonical form defined by 13.3.3.1.1, excluding any Lvalue
Transformation; the identity conversion sequence is considered to be a
subsequence of any non-identity conversion sequence) or ..."

which seems to suggest the second overload should have been selected.

I have two questions:

(1) 13.3.3.2/3 only says two such implicit conversion sequences are
distinguishable and 13.3.3.2/4 requires standard conversion sequences
to be ordered by their ranks, which seems to mean that just being
distinguishable is not enough to affect overload resolution, instead,
a ranking difference must be present for overload resolution to work.
Am I right?

(2) Another way of understanding 13.3.3.2/3 bullet one is that "the
identity conversion sequence is considered to be a subsequence of any
non-identity conversion sequence" but this "any non-identity conversion
sequence" already excludes Lvalue Transformation as said earlier in the
same sentence. Understanding it this way means the identity conversion
is not distinguishable from the array-to-pointer conversion for purpose
of overload resolution, which also explains why the code was rejected.

I wonder which of my two understanding is correct, or are they both
wrong? I expect explanations with reference to proper section of the
c++11 standard. Thanks in advance.

Best
Meng


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
rigaje
3/30/2013 6:48:43 AM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8509) is leader. Post Follow

3 Replies
559 Views

Similar Articles

[PageSpeed] 57

Am 30.03.2013 07:48, schrieb rigaje@googlemail.com:
> I have the following code.
>
> ----------------- BEGIN ----------------
> #include <cstddef>
> #include <type_traits>
>
> template <typename T0, typename T1>
> typename std::enable_if<sizeof(T0)==sizeof(T1)>::type
> inline f (T0 const* const t0, T1 const* const t1)
> {
>   // do something to *t0 and *t1
> }
>
> template <typename T0, typename T1, size_t N0, size_t N1>
> typename std::enable_if<sizeof(T0)==sizeof(T1) && N0==N1>::type
> inline f (T0 const (&t0) [N0], T1 const (&t1) [N1])
> {
>   for (size_t i = 0; i != N0; ++i)
>   {
>    // do something to t0[i] and t1[i]
>   }
> }
>
> int main ()
> {
>   size_t const a [5] {0};
>   size_t const b [5] {0};
>   f(a,b);
> }
> -----------------  END  ----------------
> It was accepted by g++-4.7.0 but rejected by 4.8.0 and all other
> compilers I have tested. These facts led me to assume the code
> should be rejected according to the standard.

That is correct.

> I realize that the array-to-pointer conversion has Exact Match rank
> according to Table 12 from 13.3.3.1.1. However, the match to the
> second overload is an identity conversion and 13.3.3.2/3 bullet one
> reads:
>
> "S1 is a proper subsequence of S2 (comparing the conversion
> sequences in the canonical form defined by 13.3.3.1.1, excluding any
> Lvalue Transformation; the identity conversion sequence is
> considered to be a subsequence of any non-identity conversion
> sequence) or ..."
>
> which seems to suggest the second overload should have been
> selected.
>
> I have two questions:
>
> (1) 13.3.3.2/3 only says two such implicit conversion sequences are
> distinguishable and 13.3.3.2/4 requires standard conversion
> sequences to be ordered by their ranks, which seems to mean that
> just being distinguishable is not enough to affect overload
> resolution, instead, a ranking difference must be present for
> overload resolution to work.  Am I right?
>
> (2) Another way of understanding 13.3.3.2/3 bullet one is that "the
> identity conversion sequence is considered to be a subsequence of
> any non-identity conversion sequence" but this "any non-identity
> conversion sequence" already excludes Lvalue Transformation as said
> earlier in the same sentence. Understanding it this way means the
> identity conversion is not distinguishable from the array-to-pointer
> conversion for purpose of overload resolution, which also explains
> why the code was rejected.
>
> I wonder which of my two understanding is correct, or are they both
> wrong? I expect explanations with reference to proper section of the
> c++11 standard. Thanks in advance.

My understanding is that the dominating rules for this example are
specified by 14.5.6.2 [temp.func.order] and in particular by 14.8.2.4
[temp.deduct.partial]. Currently there does not exist a partial
ordering between both functions, because array to pointer decay has no
ordering in the rules. There exists already a core language issue for
this unexpected outcome:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#402

Personally I would strongly prefer to see that a partial ordering will
be defined in the future.

HTH & Greetings from Bremen,

Daniel Kr�gler


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
ISO
3/30/2013 3:11:47 PM
Am 30.03.2013 07:48, schrieb rigaje@googlemail.com:
> I have the following code.
>
> ----------------- BEGIN ----------------
> #include <cstddef>
> #include <type_traits>
>
> template <typename T0, typename T1>
> typename std::enable_if<sizeof(T0)==sizeof(T1)>::type
> inline f (T0 const* const t0, T1 const* const t1)
> {
>   // do something to *t0 and *t1
> }
>
> template <typename T0, typename T1, size_t N0, size_t N1>
> typename std::enable_if<sizeof(T0)==sizeof(T1) && N0==N1>::type
> inline f (T0 const (&t0) [N0], T1 const (&t1) [N1])
> {
>   for (size_t i = 0; i != N0; ++i)
>   {
>    // do something to t0[i] and t1[i]
>   }
> }
>
> int main ()
> {
>   size_t const a [5] {0};
>   size_t const b [5] {0};
>   f(a,b);
> }

In my first response (which explains the root of the problem of this
code) I forgot to provide a workaround for your problem. If you
replace your first overload by something along then lines of

template <typename T0, typename T1>
typename std::enable_if<
    std::is_pointer<T0>::value && std::is_pointer<T1>::value &&
    sizeof(*std::declval<T0>())==sizeof(*std::declval<T1>())
  >::type
inline f (T0 const &t0, T1 const &t1)
{
   // do something to *t0 and *t1
}

there should be no ambiguity anymore with the second one. Albeit one
might feel attempted to remove the std::is_pointer constraints here
(based on the fact that we have the dereference test expressions),
they are still needed, because otherwise class types with overloaded
operator* would participate here as well.

Btw.: I think your second overload can be simplified to the declaration

template <typename T0, typename T1, std::size_t N>
typename std::enable_if<sizeof(T0)==sizeof(T1)>::type
inline f (T0 const (&t0) [N], T1 const (&t1) [N]);

HTH & Greetings from Bremen,

Daniel Kr�gler



-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
ISO
3/30/2013 3:13:12 PM
{ Please provide a small amount of quoting to establish context -mod }

Thanks for the explanation and your workaround works well.

But my primary purpose was to trying understanding overload resolution
and ranking of implicit conversions of Exact Match rank versus the
identity conversion. So let me change my example a little bit into the
following.

-------------------- BEGIN ---------------------
#include <cstddef>

inline void f (size_t const* const t0, size_t const* const t1)
{
  // do something to *t0 and *t1
}

inline void f (size_t const (&t0) [5], size_t const (&t1) [5])
{
  for (size_t i = 0; i != 5; ++i)
  {
   // do something to t0[i] and t1[i]
  }
}

int main ()
{
  size_t const a [5] {0};
  size_t const b [5] {0};
  f(a,b);
}
--------------------  END  ---------------------
This is rejected too. I understand I can make the second overload a
function template to deduce array size on the fly, thus eliminating
the ambiguity by favoring ordinary function. However, this code
illustrates my original questions clearer. Can you please reconsider
the problems based on this example? Thanks.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
rigaje
3/30/2013 11:20:18 PM
Reply:

Similar Artilces:

Overloading on a pointer and an array type
Hello everyone, I am writing a memory tracker to keep track of allocations from the 'new' and 'new[]' operators. I want to be able to distinguish between both forms, so I am looking for code similar to the following: #include <cstddef> #include <iostream> template <class T> T* TrackAllocation( T* ptr, const char* file, int line ) { std::cout << "Tracking object allocation." << std::endl; return ptr; } template <class T, std::size_t N> T* TrackAllocation( T (&arr)[N], const char* file, int line ) { std::cout <&...

Pointer to an overloaded method, error: "unresolved overloaded function type"
Error: unresolved overloaded function type g++ source.cpp 04_overloaded_unresolv.cpp: In member function `void wrapper_c::method1 ()': 04_overloaded_unresolv.cpp:75: error: no matching function for call to `wrapper_c::executeDirectly(<unresolved overloaded function type>, std::string&, std::string&)' This happens, if the method is overloaded. Do you know how this could be solved? (How to make it work with overloaded methods.) g++ -v 3.4.5 #include <iostream> #include <string> #include <vector> using std::vector; using std::string; using std::cout; ...

SFINAE with invalid function-type or array-type parameters?
Please consider this code: // snip template<typename T> char (&f(T[1]))[1]; template<typename T> char (&f(...))[2]; int main() { char c[sizeof(f<void()>(0)) == 2]; } // snap I expected it doing SFINAE and chosing the second overload, since substitution of T into T[1] yields void [1]() Which is an invalid type, of course. Adjustment of parameter types (array->pointer) is done after substituting template parameters into function parameters and checking for valid resulting types like 14.8.2 [temp.deduct] describes. But both comeau and GCC fail to compile t...

Casting from pointer types to non-pointer types
I am interfacing with a third party API (written in C, if that matters) that has an "event handler" function with the following definition: void event_handler(int event_code, unsigned long user_data); The function takes an event code along with the user data but does not act on or change the user data. In my application, I want to pass a pointer as the user data. This pointer is to an array allocated with new, say, as follows: char *array = new char[100]; and passed to the event handler as follows: event_handler(1, reinterpret_cast<unsigned long>(array)); My question is ...

mapping of XML types to C/C++ built-in types
Hello, Does W3C defines a standard for mapping XML types to C/C++ built-in types and vise versa? Thank you, Alona Hi Alona, "Alona" <allab@sympatico.ca> writes: > Does W3C defines a standard for mapping XML types to C/C++ built-in > types and vise versa? I don't think there is such a thing as XML type. Schema languages (e.g., W3C XML Schema) normally define primitive types. Some of them can be mapped to C/C++ fundamental types but I don't think W3C defines such a mapping. One proprietary mapping of XML Schema built-in types to C++ types is described in this...

One type traits class (or something like that) to get the return type of a pointer to function
Hi all. I want to build a template class to extract the return type of a pointer to function Something like: template<typename CB> class ReturnTypeExtractor { typedef ReturnType .... ??? :-( }; .... // user code typedef FooObject * (*CallBackType)(); typedef ReturnTypeExtractor<CallBackType> myReturnType; // myReturnType is FooObject * How can I accomplish this? Thanks In Advance Diego HP Diego Martins wrote: > Hi all. > > I want to build a template class to extract the return type of a > pointer to function > > Something like: > >...

Function overloading: multi dimentional array type parameter
Can some one please help me to understand C++ behaviour in function overloading. Quote: Parameter declarations that differ only in a pointer * versus an array [] are equivalent. That is, the array declaration is adjusted to become a pointer declaration (8.3.5). Only the second and subsequent array dimensions are significant in parameter types (8.3.4). Ref: ISO 14882-2003 13.1.3 2nd bullet Why is that only 2nd and subsequent array dimensions should be significant? Why not 1st dimension? Example of behaviour (quoted from ISO 14882-2003) int f(char*); int f(char[]); // same as f(char*); int f(...

Access to VO Function with Return Type ARRAY from C#
Hi NG! I am trying to Access a VO-DLL-function from C#. This works with Returns in String, Integer or Logical. Trying to Access an ARRAY return (Array of Integer) C# won't marshall the return value. Anybody here who might know how to get this working? Thanks and regards to y'all Kai Hi Kai, > I am trying to Access a VO-DLL-function from C#. This works with > Returns in String, Integer or Logical. > > Trying to Access an ARRAY return (Array of Integer) C# won't marshall > the return value. this cannot work because C# does not know about V...

Derived types with pointer arrays. Functions to extract data
Dear all, Recently I started to explore the realms of OOP in fortran 90/95. I encountered some problems with pointers in derived types, especially when (pointer) functions came into play. I browsed through quite some older threads of this news group, and the one thing I learned was: Do no use functions that return pointers, rather use subroutines instead. However I would like to be able to do something like this: ====================================== program main use obj_class implicit none type (obj) :: object real(kind=8),dimension(10) :: y call new(object) ! it is all abo...

C API needs array of C strings, what c++ type to hold it?
WWSAPI represents an array of strings as (WCHAR **array, int count). I need to allocate temporary storage for the array, and for the converted strings. Like this: array = new WCHAR *[count]; for(int i = 0; i < n; ++i) array[i] = widen(get_input(i)); What data structure should I use? I can use std::vector for the array, but what do i put in it? Note that it is passed to C, so the memory layout has to be the same. I can use the subset of C++11 supported by Visual 2010, and boost. -- Fredrik Stax\"ang | rot13: sfgk@hcqngr.hh.fr This ...

Argument type of function and safe types and types, arguments can handle safely
Groups, I have few doubts regarding argument type of function and types, arguments can handle safely. I know these issues have been discussed at multiple places on internet. I wanted to see the big picture and needed opinion of C++ gurus When you pass by value - Copy constructor is called (except for basic data type like int, float). you can pass the **same type variable** only When you pass by reference - A reference will be intialized with pass value. you can pass **non-const same type or derived type** (passing a constant type will return in error) When you pass by constant referen...

Why (type*)pointer isn't equal to *(type**)pointer?
Why (type*)pointer isn't equal to *(type**)pointer, In the code snippet, it shows that: (int *) == (int **) , (int *) != (*(int **)) . Does type-casting change the address? or doesn't type-casting do anything? 1 int main(void) 2 { 3 char ch; 4 int *p; 5 int *p2; 6 int *p3; 7 8 ch = 'c'; 9 p = (int *)(&ch); 10 p2 = *(int **)(&ch); 11 p3 = (int **)(&ch); 12 13 printf("%c", *p); 14 printf("%c", *p2); /* error...

What is the purpose of type() and the types module and what is a type?
The type() builtin according to python docs, returns a "type object". http://docs.python.org/2/library/types.html And in this module is bunch of what I assume are "type objects". Is this correct? http://docs.python.org/2/library/functions.html#type And type(), aside from being used in as an alternative to a class statement to create a new type, really just returns the object class, doesn't it? >>> import types >>> a = type(1) >>> b = (1).__class__ >>> c = int >>> d = types.IntType >>> a is b is c is...

Calling C++ functions in C function through function pointers
Hi All!! I have a C++ program that uses callback funtions which are the private members of class. The code uses an API wrtiiten in C which supplies callback-setting functions that require pointers to these functions... The funtions wherein these API's callback-setting functions are called, are public members of the same class of which the callbacks are the private member. Now the API functions are generating compile errors since they cannot "understand" the C++ function pointers. Consider the sample code: class classname { public : /* Constructor for the class...

Calling C++ functions in C function through function pointers
Hi All!! I have a C++ program that uses callback funtions which are the private members of class. The code uses an API wrtiiten in C which supplies callback-setting functions that require pointers to these functions... The funtions wherein these API's callback-setting functions are called, are public members of the same class of which the callbacks are the private member. Now the API functions are generating compile errors since they cannot "understand" the C++ function pointers. Consider the sample code: class classname { public : /* Constructor for the class...

function returning function pointer (recursive type)
Hi group, only today I stumbled over the famous (?) inability of C to define recursive types for functions. The task was to define a daisy chain of functions which facilitate insertion and deletion by passing and returning function pointers of their very own type. Each function should hold a static variable to its' successor. After having unwound my brain from the infinite recursion that happened in the first typedef (*)()(*foo)((*)(...etc. I rummaged the comp.lang.c archives and found the explanation with a workaround based on structs. I remember however that function pointers can be cast...

Do not cast pointers to functions to pointers to primitive types
Not sure if this is the right place or OT. One of the Parasoft coding guidelines (which I am using for current project) is "Do not cast pointers to functions to pointers to primitive types [CODSTA-09-3]" EXAMPLE(from parasoft document): void Foo(char *ptrC) { *ptrC = 0; return; } void f() { void *ptrV = 0; void (*funPtr) (char*) = 0; funPtr = &Foo; ptrV = (void*)funPtr; // Violation of the rule and raise error return; } I can see why it is a bad idea not to write code this way. But can any one explain where this kind of co...

How to devise function pointer type from function name?
Hi, Can I devise function pointer type from function name by using template programming? e.g. I have function: exertn =93C=94 void xmlFreeDoc(xmlDocPtr cur); I want something like following: typeof(xmlFreeDoc) functionpointer =3D xmlFreeDoc; i.e value to type conversion I want pass this type to Holder which will call this function in dtor. Currently I am using following code to do the same task: extern "C" { typedef void (*funcPtr)(void*) ; } Holder<xmlChar, funcPtr, false> val(xmlNodeListGetString(doc, cur_node- >children, 1), xmlFree); Issues with above code: I need to ...

How to devise function pointer type from function name?
Hi All, Can I devise function pointer type from function name by using template programming? e.g. I have function: exertn �C� void xmlFreeDoc(xmlDocPtr cur); I want something like following: typeof(xmlFreeDoc) functionpointer = xmlFreeDoc; i.e value to type conversion I want pass this type to Holder which will call this function in dtor. Currently I am using following code to do the same task: extern "C" { typedef void (*funcPtr)(void*) ; } Holder<xmlChar, funcPtr, false> val(xmlNodeListGetString(doc, cur_node- >children, 1), xmlFree); Issues with above code: I need to ad...

"C
Dear all, I'm experiencing an issue about local and not local pointers... I've N clients and one server that communicate each other. The N clients retrieve data dynamically, send it to the server throgh enrty call (obviously the server can accept just one call per time) and wait for the reply from the server (through accept statement). For this reason the server needs to know on which client call the entry: one time could be the 3th, another the 1st and so on... This is my - deeply simplified - framework: package P1 is task type T1 is entry Retrieve_Data(Data : String); end T1...

C,C++ allows pointers to incomplete types
Hello All, C,C++ allows pointers to incomplete types. // C,C++ allows pointers to incomplete types. typedef struct hashmap_item *hashmap_item_t; struct hashmap_item { hashmap_item_t prev; hashmap_item_t next; char* key; void* value; int time_added; }; // Till this point the structure is incomplete. Could someone explain to me why it works? And other closely related quarks that I may not know of? Regards, \Emeka janus <emekamicro@gmail.com> writes: >C,C++ allows pointers to incomplete types. >Could someone explain to me why it works? ...

C++ typed interface to hundreds of C functions
Hi there, I'm handling pointers to "objects" described by C-style struct (e.g. Base), and I manipulate them through a low level C API. Sometimes a third-party binary function is applied to two of these, giving a pointer to a third. extern "C" Base *foo1_A1_B1_C1(Base *, Base *); extern "C" Base *foo1_A1_B1_C2(Base *, Base *); extern "C" Base *foo1_A1_B2_C1(Base *, Base *); ... etc. (hundreds more) I'd like to provide a better interface to this using class templates for the A,B and C parts: Derived<A,B,C> *foo1(Derived<A,B,C> &a...

Can a (non-static) data member use "Type{Whatever}" in its brace/list initializer when "Type" is a C-level array?
I have code like (skipping the base-case specialization): template < typename Number, std::size_t Rank > struct complex_rt { using size_type = std::size_t; static constexpr size_type rank = Rank; using value_type = Number; //... template < typename T, size_type R, typename ...U, typename = typename std::enable_if<(R < rank - 1u)>::type, typename = typename std::enable_if<((1u + sizeof...( U )) <= (1ULL << ( rank - R )))>::type, typename = typename std::enable_if<std::is_convertible<T, value_type>::value>::type > constexpr complex_rt( complex_rt<T, R> const &first, complex_rt<U, R> const &...rest ) : complex_rt{ 0u, (typename std::remove_extent< complex_rt<value_type, R>[][1ULL << ( rank - R )] >::type){first, rest...} } {} //... private: using barrage_type = complex_rt<value_type, rank - 1u>; template < size_type N > explicit constexpr complex_rt( size_type i, barrage_type const (&bb)[N] ) : b{ bb[i], bb[i + 1u] } {} // assert( i <= N - 2 ) template < size_type R, size_type N, typename = typename std::enable_if<(R < rank - 1u)>::type > explicit constexpr complex_rt( s...

C++ error using non-type template argument of member function pointer defaulted to 0
The code: template <typename C, void (C::*g)() = 0, void (C::*s)() = 0> struct ATemplate { }; struct TestBugClass { void AFunc() {} ATemplate<TestBugClass,&TestBugClass::AFunc,0> inst; }; Under VC9 this compiles without error but Comeau online gives me: "ComeauTest.c", line 1: error: argument of type "int" is incompatible with template parameter of type "void (C::*)()" template <typename C, void (C::*g)() = 0, void (C::*s)() = 0>" etc. I see nothing wrong with initializing a member function non-type template parameter t...

Web resources about - function overload with array types and pointer types - comp.lang.c++.moderated

Wave function - Wikipedia, the free encyclopedia
... (a ball attached to a spring ) in classical mechanics (A-B) and quantum mechanics (C-H). In quantum mechanics (C-H), the ball has a wave function ...

Eating chocolate 'improves brain function' - study
... news for those with a sweet tooth - a recent study has found that regular chocolate consumption is associated with better cognitive function. ...

Resource sector may outsource finance functions to Asia
Outsourcing financial functions to Asia is one tactic struggling Australian energy and resources companies may use this year to survive the slump ...

Using Functions to Make Better Abstractions
... (code that is tightly coupled to its own implementation details). I was wrong. I was wrong because I had an incomplete understanding of functions. ...

Media devices sold to feds have hidden backdoor with sniffing functions
... AMX NX-1200 , a programmable device used to control AV and building systems. The researchers first became suspicious after encountering a function ...

A Non-Sokratic Dialogue on Social Welfare Functions: Hoisted from the Archives from 2003
**[A Non-Sokratic Dialogue on Social Welfare Functions: Hoisted from the Archives from 2003](http://www.j-bradford-delong.net/movable_type/2 ...

Here's how squads and iron sights will function in Rising Storm 2: Vietnam
... roles and create a squad, and the creator can name, lock, or invite others to their little group. The more an outfit fills up, the more functions ...

Yahoo Begins Grim Job of Closing Functions, Laying Off Staff
Yahoo Food is closing, and other digital magazines on tech, travel and beauty are also scheduled for closing or major cutbacks.

Don’t tase me, bro: Study shows being shocked by a Taser disrupts brain function
Researchers at Drexel shot a bunch of college students with 50,000 volts. The result? Short-term declines in cognitive function comparable with ...

How The U.S. Supreme Court Will Function Without Justice Scalia
... but in a fashion that could have frustrating ramifications for a number of major cases set to be decided. Here's how the court will function, ...

Resources last updated: 2/22/2016 3:27:22 PM