- wording: "references cannot be null" - 4 Updates
- Quick Question - functors via structs - 9 Updates
- The members of ::std::initializer_list - 6 Updates
- The members of ::std::initializer_list - 2 Updates
- int32_t vs. int64_t vs. long: Ambiguous - 2 Updates
- What the wrong with the given code, Can some one tell me the correct one and do tell me the problem in the original one - 2 Updates
Christopher Pisz <nospam@notanaddress.com>: May 05 10:37AM -0500 On 5/5/2015 10:24 AM, Stefan Ram wrote: > void f( V * & q ){ ::std::cout << q->i << '\n'; } > int main(){ V * p = nullptr; f( p ); } > »q« is a reference, and it /is/ null! No, q is a reference to a pointer that exists, and the pointer is null. -- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble", and "Islam" So, I won't be able to see or respond to any such messages --- |
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: May 05 05:46PM +0200 > void f( V * & q ){ ::std::cout << q->i << '\n'; } > int main(){ V * p = nullptr; f( p ); } > »q« is a reference, and it /is/ null! No. q is a reference to a pointer, and the pointer's value is nullptr. I.e., q refers to something that exists in a valid state (the variable p of main). In the body of f(), writing "q = ...any pointer to a V..." is perfectly ok. What you do instead is: accessing the value pointed to by the pointer referenced by q. The former part (accessing the value pointed to...) is faulty, the latter (the pointer referenced by q) is valid. You can still create an invalid reference: V * p = nullptr; V & q = *p; but imho the initialization has undefined behavior because you dereference an invalid pointer (even though you do not really dereference it). -- Alain. |
Mel <mel@zzzzz.com>: May 05 06:07PM +0200 > void f( V * & q ){ ::std::cout << q->i << '\n'; } > int main(){ V * p = nullptr; f( p ); } > »q« is a reference, and it /is/ null! Nope, q is not null, rather pointer which it refers... -- Press any key to continue or any other to quit |
Melzzzzz <mel@zzzzz.com>: May 05 06:55PM +0200 On 5 May 2015 16:26:57 GMT > something that can be understood by all those who can guess what the > intended meaning is, but might not be true by a strict reading of the > wording. You don't understand at all what references are about. You could write void f(V *q) and get same result.... |
Paavo Helde <myfirstname@osa.pri.ee>: May 04 11:28PM -0500 Doug Mika <dougmmika@gmail.com> wrote in > Afterall the decleration of map states that it takes a binary > predicate, then why isn't it an object of a functor > (ReverseSort<int>()) instead of just a type (ReverseSort<int>)?? Because templates are instantiated with a type (or a compile-time integral constant, but this does not apply here). An object is not a type. Type is a compile-time concept and object is a run-time concept, and template instantiation happens at compile time only. Maybe you are confusing the template parameter with the map constructor parameter. The map constructor indeed has a comp parameter for taking the comparator object. By default it uses a default-constructed object of the relevant type, but you can pass it also explicitly: map<int, string, ReverseSort<int> > myMap (someOtherMap.cbegin(), someOtherMap.cend(), ReverseSort<int>()); Note the parens near the end. hth Paavo |
Victor Bazarov <v.bazarov@comcast.invalid>: May 05 08:36AM -0400 On 5/4/2015 6:40 PM, Doug Mika wrote: > } > The problem is with my template function ReverseSort<int>, but why > can't I include it as the binary predicate in map? What does your compiler say? Can you not take a hint from its error message? ReverseSort<int> is not a type, you can't use it as the third argument to the 'std::map' template. V -- I do not respond to top-posted replies, please don't ask |
Doug Mika <dougmmika@gmail.com>: May 05 08:06AM -0700 So let me see if I understand this correctly. Template Classes are instantiated with a type, not an object...that makes sense. So I just have to remember that when instantiating a template, I have to use the type NOT an object...and Paavo's explenation made sense. Now however, let's say that as my binary predicate for the map decleration I would like to use a template FUNCTION (not a template CLASS). That is, as my predicate I would like to use the following function: template<typename KeyType> bool ReverseSort(const KeyType& key1, const KeyType& key2){ return (key1 > key2); } Since this is a template function not a template object, how would I declare a map to use this function as it's binary predicate? None of the ones below work? Why? map<int, string, ReverseSort> mapIntToString (someOtherMap.cbegin(), someOtherMap.cend()); map<int, string> mapIntToString3 (mapIntToString1.cbegin(), mapIntToString1.cend(),ReverseSort<int>); map<int, string> mapIntToString3 (mapIntToString1.cbegin(), mapIntToString1.cend(),ReverseSort); |
legalize+jeeves@mail.xmission.com (Richard): May 05 03:06PM [Please do not mail me a copy of your followup] Doug Mika <dougmmika@gmail.com> spake the secret code >and NOT >map<int, string, ReverseSort<int>() > someOtherMap >(someOtherMap.cbegin(), someOtherMap.cend()); Templates arguments can be types or an integral or enumeration type value.[1] std::map takes four template parameters: - class Key - class T - class Compare = std::less<Key> - class Allocator = std::allocator<std::pair<const Key, T>> ReverseSort is defined as: template<typename KeyType> struct ReverseSort{ bool operator()(const KeyType& key1, const KeyType& key2){ return (key1 > key2); } }; ReverseSort<int> is a type, an instantiation of the template struct ReverseSort with a template argument of int. ReverseSort<int>() is an (anonymous) instance of the type ReverseSort<int>. Templates cannot take instances of objects as template arguments, only types or integral values. [1] This is slightly simplified, see 14.3.2 Template non-type arguments in the standard for details. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Doug Mika <dougmmika@gmail.com>: May 05 08:36AM -0700 Yes, so how would I instantiate a map object if I wanted to use the following template FUNCTION as my sort predicate: template<typename KeyType> bool ReverseSort(const KeyType& key1, const KeyType& key2){ return (key1 > key2); } ??? |
Victor Bazarov <v.bazarov@comcast.invalid>: May 05 11:50AM -0400 On 5/5/2015 11:06 AM, Doug Mika wrote: > So let me see if I understand this correctly. Template Classes are instantiated with a type, not an object...that makes sense. So I just have to remember that when instantiating a template, I have to use the type NOT an object...and Paavo's explenation made sense. > Now however, let's say that as my binary predicate for the map decleration I would like to use a template FUNCTION (not a template CLASS). That is, as my predicate I would like to use the following function: > bool ReverseSort(const KeyType& key1, const KeyType& key2){ > return (key1 > key2); > } That's not a *function*. It's a *function template*. You can't *use* this one, you can only instantiate it and use an instantiation. > Since this is a template function not a template object, how would I declare a map to use this function as it's binary predicate? > map<int, string, ReverseSort> mapIntToString (someOtherMap.cbegin(), someOtherMap.cend()); > map<int, string> mapIntToString3 (mapIntToString1.cbegin(), mapIntToString1.cend(),ReverseSort<int>); > map<int, string> mapIntToString3 (mapIntToString1.cbegin(), mapIntToString1.cend(),ReverseSort); All class templates that use comparators are implemented in such a way that a function cannot be use do instantiate those templates. You need either a lambda or a functor. V -- I do not respond to top-posted replies, please don't ask |
Victor Bazarov <v.bazarov@comcast.invalid>: May 05 11:59AM -0400 On 5/5/2015 11:36 AM, Doug Mika wrote: > Yes, so how would I instantiate a map object if I wanted to use the following template FUNCTION as my sort predicate: > return (key1 > key2); > } > ??? I keep forgetting about 'function' template... See if this works for you: #include <string> #include <map> #include <functional> #include <iostream> using namespace std; template<typename KeyType> bool ReverseSort(const KeyType& key1, const KeyType& key2){ return (key1 > key2); } int main() { //The Program map<int, string, function<bool(const int&, const int&)>> mapIntToString1(ReverseSort<int>); mapIntToString1[1] = "one"; mapIntToString1[2] = "two"; mapIntToString1[3] = "three"; mapIntToString1[4] = "four"; for (auto m : mapIntToString1) { cout << m.first << "," << m.second << endl; } } V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): May 05 04:09PM [Please do not mail me a copy of your followup] Victor Bazarov <v.bazarov@comcast.invalid> spake the secret code > map<int, string, function<bool(const int&, const int&)>> > mapIntToString1(ReverseSort<int>); That works. Details of std::function template class: <http://en.cppreference.com/w/cpp/utility/functional/function> -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Doug Mika <dougmmika@gmail.com>: May 05 09:51AM -0700 Yes that worked nicely, and I'll admit, I haven't yet read about the std::function template but I hope someone could quickly explain the following line: map<int, string, function<bool(const int&, const int&)>> mapIntToString1(ReverseSort<int>); function<bool(const int&, const int&)> - defines type as function that takes two int's and returns a bool. Check mapIntToString1(ReverseSort<int>) - calls the constructor of map that takes key_compare as argument, in this case a function pointer. Is this correct? |
ram@zedat.fu-berlin.de (Stefan Ram): May 05 03:05PM Can someone explain why the type ::std::initializer_list does not have some convenience members that some programmers might expect? IIRC, it's members can be stored in ROM, but why does an ::std::initializer_list l has l.begin() ::std::begin( l ) but no l.cbegin() ::std::cbegin( l ) , and why is there no l[ size_t ] l.at( size_t ) ? |
ram@zedat.fu-berlin.de (Stefan Ram): May 05 03:17PM When a value is returned, its expression is automatically considered to be an rvalue and thus is /moved/ from although the literal meaning in early C++ once might have been that its value is being copied. This is known as "return value optimization" ("RVO"). Does the same apply to arguments in the following sense? When a function f has a plain ::std::string parameter and is called f( "a"s + "b"s ) , then »"a"s + "b"s« is a temporary, so it does not have to be copied from but can be moved from. Is this guaranteed to happen? Is there a name for this "optimization" (akin to "RVO")? So, if it is guaranteed that it will happen for f( ::std::string const s ) , then one does not need to write f( ::std::string && s ) . Then, what are the use-cases for »f( ::std::string && s )«? PS: I wrote the following program trying to see which constructors are invoked under the C++ implementation used: #include <ostream> #include <initializer_list> #include <memory> struct V { V( ::std::initializer_list< int >const l ): use{ *::std::begin( l )} { ::std::cout << "V( ::std::initializer_list< int >const l )\n"; } V( V const & other ): use{ other.use } { ::std::cout << "V( V const & other )\n"; } V( V && other ): use{ other.use }{ ::std::cout << "V( V && other )\n"; } int use; }; void f( V const v ) { ::std::cout << "f( V const v )" << '\n'; ::std::cout << v.use << '\n'; } void g( V && v ) { ::std::cout << "g( V && const v )" << '\n'; ::std::cout << v.use << '\n'; } int main() { f( V{ 2 } ); g( V{ 2 } ); } V( ::std::initializer_list< int >const l ) f( V const v ) 2 V( ::std::initializer_list< int >const l ) g( V && const v ) 2 In this case, one cannot see any difference between when the value parameter in »f« and the rvalue parameter in »g« is being used. |
ram@zedat.fu-berlin.de (Stefan Ram): May 05 03:24PM When asked for the difference between pointers and references some say that references cannot be null. I know what this is /intended/ to mean, but the wording might not correctly convey this for readers who do not yet known this. For an example how this can be (mis)understood, I show the following program that has a reference that /is/ null! #include <iostream> #include <ostream> struct V { int i; }; void f( V * & q ){ ::std::cout << q->i << '\n'; } int main(){ V * p = nullptr; f( p ); } »q« is a reference, and it /is/ null! |
ram@zedat.fu-berlin.de (Stefan Ram): May 05 04:07PM >I hope you're not going to ask next why pointers and arrays don't have >members like 'cbegin' or 'rend'... Well, for arrays ... #include <iostream> #include <ostream> #include <memory> #include <vector> int main() { ::std::cout << __cplusplus << '\n'; ::std::vector< int >a{ 1, 2, 3 }; for( auto p = ::std::cbegin( a ); p != ::std::cend( a ); ++p ) ::std::cout << *p << '\n'; } 201402 1 2 3 And all of a sudden, it also works with initializer lists! My problem was actually that I did not manage before to force my compiler into C++14 mode before! #include <iostream> #include <ostream> #include <memory> #include <initializer_list> int main() { ::std::cout << __cplusplus << '\n'; ::std::initializer_list< int >a{ 1, 2, 3 }; for( auto p = ::std::cbegin( a ); p != ::std::cend( a ); ++p ) ::std::cout << *p << '\n'; } 201402 1 2 3 |
ram@zedat.fu-berlin.de (Stefan Ram): May 05 04:26PM >Nope, q is not null, rather pointer which it refers... The following prints »true«. #include <iostream> #include <ostream> #include <ios> struct V { int i; }; void f( V * & q ){ ::std::cout << ::std::boolalpha <<( q == 0 )<< '\n'; } int main(){ V * p = nullptr; f( p ); } Saying, »q is not null«, when in fact »q == 0« /is/ true, is something that can be understood by all those who can guess what the intended meaning is, but might not be true by a strict reading of the wording. |
ram@zedat.fu-berlin.de (Stefan Ram): May 05 04:42PM >>::std::vector< int >a{ 1, 2, 3 }; >>for( auto p = ::std::cbegin( a ); p != ::std::cend( a ); ++p ) >Yes, but those are not *members*. Oops! I did want to actually /use/ arrays. You already replied as if I did, but for correctness' sake I'd like to show the actual working code with an actual array: int a[]{ 1, 2, 3 }; for( auto p = ::std::cbegin( a ); p != ::std::cend( a ); ++p ) BTW, there's a paper by, IIRC, Sutter (et al.?), where they suggest a "uniform call syntax", IIRC, that was to enable the member call syntax even for non-members. |
Victor Bazarov <v.bazarov@comcast.invalid>: May 05 11:30AM -0400 On 5/5/2015 11:05 AM, Stefan Ram wrote: > l[ size_t ] > l.at( size_t ) > ? Most likely *because* those were deemed unnecessary or unnecessarily difficult to implement. An initializer list is not a container. Its purpose is to assist initialization, that's all. I hope you're not going to ask next why pointers and arrays don't have members like 'cbegin' or 'rend'... Besides, the rationales behind language design decisions are discussed in comp.std.c++. Consider posting there, if you are really interested and not just venting some kind of frustration, OK? V -- I do not respond to top-posted replies, please don't ask |
Victor Bazarov <v.bazarov@comcast.invalid>: May 05 12:35PM -0400 On 5/5/2015 12:07 PM, Stefan Ram wrote: > { ::std::cout << __cplusplus << '\n'; > ::std::vector< int >a{ 1, 2, 3 }; > for( auto p = ::std::cbegin( a ); p != ::std::cend( a ); ++p ) Yes, but those are not *members*. > 1 > 2 > 3 V -- I do not respond to top-posted replies, please don't ask |
Juha Nieminen <nospam@thanks.invalid>: May 05 10:18AM > long long, not as long. The standard says int64_t must be a typedef, but > does not say of which type. And it cannot be a typedef of long and long > long at the same time - these are required to be different types. That doesn't really explain why foo(short(123)) compiles just fine even though neither version of the function is an exact match, and either one could be a valid match. Clearly short is a distinct type from int32_t and int64_t (yet it matches int32_t unambiguously). I don't understand why a 64-bit long can't match int64_t given that they are identical in size and signedness. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
legalize+jeeves@mail.xmission.com (Richard): May 05 02:58PM [Please do not mail me a copy of your followup] Vir Campestris <vir.campestris@invalid.invalid> spake the secret code >> foo(static_cast<std::int64_t>(123)); >I don't see why this would make it compile OK giving it 123, 123 is the argument to static_cast<> which explicitly promotes the integral constant 123 to the type std::int64_t and the overload for that type is selected. >but not >123L. (you snipped "Note that if I call foo(123) it does not >give any error.") 123 is an integer literal with no type suffix. An integer literal with no type suffix tells the compiler to pick the smallest type that can hold the literal. For a decimal literal with no suffix, the type chosen is the first of int, long int, or long long int that can hold the value[1]. In your case, this is int. std::int32_t on your implementation is apparently a typedef for int. So calling foo(123) does work, but it doesn't call the 64-bit overload. [1] See section 2.14.2 Integer Literals in the standard -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Cholo Lennon <chololennon@hotmail.com>: May 05 10:27AM -0300 On 05/04/2015 04:35 AM, koolAMit wrote: >> writing C++ code. It looks like C# to me, which is a completely >> different language. > Ya Its C#, I thought Some one knows it, So I post it. You should post in "microsoft.public.dotnet.languages.csharp" -- Cholo Lennon Bs.As. ARG |
FredK <fred.l.kleinschmidt@gmail.com>: May 05 07:50AM -0700 On Tuesday, May 5, 2015 at 6:28:10 AM UTC-7, Cholo Lennon wrote: > > Ya Its C#, I thought Some one knows it, So I post it. > You should post in "microsoft.public.dotnet.languages.csharp" The main problem seems to be that the body of GetFriendsOfDegree() has not been written. -- Fred K |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment