- Defining operator == - 1 Update
- Possibly useful technique for templatizing const and non-const method variants - 5 Updates
- Defining operator == - 4 Updates
- Christianity is a relationship between God and man - 1 Update
- Christianity is not a religion - 1 Update
- The Rapture (Reprise) - 1 Update
- Christ offers to people - 1 Update
- The Rapture (Reprise Reprise) - 1 Update
- The Rapture (Reprise ad infinitum) - 1 Update
- The Virgin Birth and Creationism - 1 Update
- Sunday School - 1 Update
- Hodgin - 2 Updates
Bo Persson <bop@gmb.dk>: Jan 07 11:35PM +0100 On 2018-01-07 19:04, Stefan Ram wrote: > B's comparison accepts conversions for its second > operand, but not its first. > (end of quotation) This of course assumes that you WANT a conversion of the operands, and intend to compare a derived class to the base class. If not, the member works fine. Bo Persson |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 07 12:16PM +0100 This is possibly a technique that others (e.g. you?) might find useful, for avoiding redundancy for the case where a bunch of methods should each have non-const and const version, but with the same code. One severe limitation is that as I can't see any good way to support virtual methods this way? Code (the cppx::* stuff is omitted here, it's pretty trivial): ---------------------------------------------------------------------- #pragma once #include <cppx/constness.hpp> // cppx::const_like_ #include <cppx/class-kind/No_copy.hpp> #include <npp/Encoding_config.hpp> // npp::Encoding_config #include <npp/paths.hpp> // npp::path_to_gui_config #include <stdlib/extension/hopefully_and_fail.hpp> #include <stdlib/filesystem.hpp> // std::filesystem::* #include <stdlib/memory.hpp> // std::unique_ptr #include <stdlib/string.hpp> // std::string #include <wrapped-tinyxml2/all.hpp> // tinyxml2::* namespace npp { using namespace std::literals; using namespace stdlib::ext::hopefully_and_fail; using namespace stdlib::ext::type_builders; namespace fs = std::filesystem; namespace tx2 = tinyxml2; using cppx::const_like_; using cppx::Constness; using cppx::No_copy; using cppx::with_constness_; using std::string; using std::unique_ptr; using stdlib::ext::char_path_or_x; using Path = fs::path; class Config; namespace config_impl { template< class Type > auto non_null( ref_<const string> msg, const ptr_<Type> p ) -> ptr_<Type> { hopefully( p != nullptr ) or fail( "npp::Config::" + msg ); return p; } template< Constness::Enum constness > // m or c, for mutable or const class Const_adaptation_ { protected: using Self = with_constness_<constness, Config>; static auto root( ref_<Self> self ) -> ptr_<const_like_<Self, tx2::XMLElement>> { return non_null( "root - no xml root element", self.p_xml_->RootElement() ); } static auto gui_configs( ref_<Self> self ) -> ptr_<const_like_<Self, tx2::XMLElement>> { return non_null( "gui_configs - no xml GUIConfigs element", root( self )->FirstChildElement( "GUIConfigs" ) ); } static auto config_of_new_doc( ref_<Self> self ) -> ptr_<const_like_<Self, tx2::XMLElement>> { auto p_config = gui_configs( self )->FirstChildElement(); while( p_config != nullptr ) { const ptr_<const char> p_name = p_config->Attribute( "name" ); if( p_name != nullptr and p_name == "NewDocDefaultSettings"s ) { break; } p_config = p_config->NextSiblingElement(); } return non_null( "config_of_new_doc - no xml element named NewDocDefaultSettings", p_config ); } }; } // namespace config_impl class Config : public No_copy , private config_impl::Const_adaptation_<Constness::m> , private config_impl::Const_adaptation_<Constness::c> { unique_ptr<tx2::XMLDocument> p_xml_; // Dynamic in order to be non-const. using Consted = config_impl::Const_adaptation_<Constness::c>; friend Consted; using Mutable = config_impl::Const_adaptation_<Constness::m>; friend Mutable; using Consted::config_of_new_doc; using Mutable::config_of_new_doc; public: auto default_encoding() const -> Encoding_config { return Encoding_config{ *config_of_new_doc( *this ) }; } void set_default_encoding( ref_<const Encoding_config> values ) { values.set_as_attributes_in( *config_of_new_doc( *this ) ); } auto to_string() const -> string { tx2::XMLPrinter printer; p_xml_->Print( &printer ); return printer.CStr(); } Config( ref_<const Paths> paths = {} ) : p_xml_{ new tx2::XMLDocument{} } { const Path config_path = paths.gui_config_file(); hopefully( fs::exists( config_path ) ) or fail( "npp::Config::<init> - specified config file doesn't exist" ); const string ansi_config_path = char_path_or_x( config_path ); p_xml_->LoadFile( ansi_config_path.c_str() ) >> Success{} or fail( "npp::Config::<init> - tinyxml2::XMLDocument::LoadFile failed" ); //hopefully( xml_.RootElement()->Name() == "NotepadPlus"s ) // or fail( "npp::Config::<init> - XML root element is not "NotepadPlus"" ); } }; } // namespace npp ---------------------------------------------------------------------- Cheers! - Alf |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 07 05:08PM On 07/01/2018 11:16, Alf P. Steinbach wrote: > }; > } // namespace npp > ---------------------------------------------------------------------- Sorry Alf but your code is an over-engineered, overly complicated unreadable mess. This is all you need to do to simply and elegantly solve the problem: const foo& bar::baz() const { ... } foo& bar::baz() { return const_cast<foo&>(const_cast<const bar*>(this)->baz()); } /Flibble -- "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 07 08:45PM +0100 On 1/7/2018 6:08 PM, Mr Flibble wrote: >> This is possibly a technique that others (e.g. you?) might find >> useful, for avoiding redundancy for the case where a bunch of methods >> should each have non-const and const version, but with the same code. <snip> > { > return const_cast<foo&>(const_cast<const bar*>(this)->baz()); > } Perhaps you thought that there exists cases where it can be a good idea to do what you do here, hence it must always be the best idea on Earth, with no need for anything else. Essentially, with the casts you're giving up static type checking, which of course can be fine -- and often is fine, that's why we have casts. But it's not a general solution: in some cases your code's const_cast<foo&> can lead to Undefined Behavior, namely when the foo is original const (and that includes when it's dynamically allocated as const) and the resulting reference is used. So you appear, at best, to not have understood the purpose of a cast-free approach. I'm sorry, but that means your evaluation is not worth shit. Cheers!, - Alf |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 07 08:42PM On 07/01/2018 19:45, Alf P. Steinbach wrote: > to do what you do here, hence it must always be the best idea on Earth, > with no need for anything else. > Essentially, with the casts you're giving up static type checking, which The casts comply with static type checking (unlike reinterpret_cast or C-style cast which I am not using) so this first claim of yours is bullshit. > original const (and that includes when it's dynamically allocated as > const) and the resulting reference is used. So you appear, at best, to > not have understood the purpose of a cast-free approach. Obviously the intention here is to return a reference to something that is non-const (as we are calling non-const baz()). You will only get undefined behaviour if you invoke undefined behaviour. You only have a bug if you write a bug so your second claim is diversionary tactic at best and bullshit at worst. > I'm sorry, but that means your evaluation is not worth shit. Try again Alf; your solution is egregious and my solution is simple and all that is required. /Flibble -- "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 07 09:00PM On 07/01/2018 20:42, Mr Flibble wrote: >> I'm sorry, but that means your evaluation is not worth shit. > Try again Alf; your solution is egregious and my solution is simple and > all that is required. Of course for the few cases where my solution would invoke UB you would simply write a friend function template that the const and non-const member functions call rather than use the over-engineered mess that you are proposing. /Flibble -- "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 07 04:33PM For a class, Herb Sutter once recommended to write inline pair operator +( pair result, pair const & other ) { result += other; return result; } outside of the class specifier and then in the class specifier: pair & operator +=( const pair & o ) { x += o.x; y += o.y; return *this; } . So, now I want to implement inline bool operator ==( const pair & l, const pair & r ) outside of the class specifier (as I believe it should be). Should I now write l.x == r.x && l.y == r.y into the definition of »operator ==« and add it as a friend to the class (»x« and »y« are private) or should I rather write inline bool operator ==( const pair & l, const pair & r ) { return l.equals( r ); } and add a function bool equals( const pair & other )const { return this->x == other.x && this->y == other.y; } within the class specifier? |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 07 04:38PM >inline bool operator ==( const pair & l, const pair & r ) >outside of the class specifier (as I believe it should >be) I see examples, where Sommerlad writes bool operator==(Ring const &r) const { return val == r.val; } /into/ the class specifier. Now I'm really confused about how to proceed. If one implements a class for pairs of two ints, what is the most recommendable way to implement operator ==? |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 07 05:42PM >ram@zedat.fu-berlin.de (Stefan Ram) writes: >>inline bool operator ==( const pair & l, const pair & r ) >bool operator==(Ring const &r) const { It seems that a common pattern is as follows: »operator ==« is declared outside of the class specifier /if/ this is possible (i.e., if there already are public members of the class that can be used for this purpose). But when it is not possible, one does not add it as a friend nor does one add more public members to the class, but one rather moves the declaration of »operator==« into the class specifier. |
ram@zedat.fu-berlin.de (Stefan Ram): Jan 07 06:04PM >nor does one add more public members to the class, but one >rather moves the declaration of »operator==« into the class >specifier. But then, (begin of quotation) C.86: Make == symmetric with respect to operand types and noexcept Reason: Assymetric treatment of operands is surprising and a source of errors where conversions are possible. == is a fundamental operations and programmers should be able to use it without fear of failure. Example: class X { string name; int number; }; bool operator==(const X& a, const X& b) noexcept { return a.name==b.name && a.number==b.number; } Example, bad: class B { string name; int number; bool operator==(const B& a) const { return name==a.name && number==a.number; } // ... }; B's comparison accepts conversions for its second operand, but not its first. (end of quotation) An issue with the first example from the C++ Core Guidelines from 2015 quoted above is that it does not compile, however, because »name« is private. In the guidelines of 2018, this is changed to »struct B«, which does not answer the question what exactly to do when the members /are/ private. But still, everybody seems to try hard to avoid »friend«. They'd rather make it a »struct«. |
mcheung63@gmail.com: Jan 07 08:56AM -0800 Chris M. Thomasson於 2018年1月1日星期一 UTC+8上午6時50分24秒寫道: > Is it okay to have a pole that is not made of aluminum? > ;^) > [...] Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:55AM -0800 mche...@gmail.com於 2018年1月1日星期一 UTC+8上午11時14分43秒寫道: > directly and personally. > -- > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:55AM -0800 Rick C. Hodgin於 2018年1月6日星期六 UTC+8上午5時53分48秒寫道: > Reported to abuse@giganews.com. > -- > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:55AM -0800 Rick C. Hodgin於 2018年1月7日星期日 UTC+8上午2時03分51秒寫道: > confusing intrusion into your life. > -- > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:55AM -0800 Rick C. Hodgin於 2018年1月7日星期日 UTC+8上午2時32分53秒寫道: > sin, the same will be saved. The rest will not. > -- > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:55AM -0800 Rick C. Hodgin於 2018年1月7日星期日 UTC+8上午2時37分08秒寫道: > confusing intrusion into your life. > -- > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:54AM -0800 Rick C. Hodgin於 2018年1月7日星期日 UTC+8上午2時44分20秒寫道: > confusing intrusion into your life. > -- > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
mcheung63@gmail.com: Jan 07 08:54AM -0800 Rick C. Hodgin於 2018年1月7日星期日 UTC+8上午4時14分08秒寫道: > -- > Thank you, > Rick C. Hodgin Rick c. Hodgin's mother is died by cancer, god did a good job |
Lynn McGuire <lynnmcguire5@gmail.com>: Jan 06 07:26PM -0600 On 1/6/2018 11:59 AM, Mr Flibble wrote: > Will the real Slim Shady please stand up? :) > /Flibble There seems to be about five of them now. And the spam is on comp.lang.c also. Lynn |
mcheung63@gmail.com: Jan 07 08:54AM -0800 Lynn McGuire於 2018年1月7日星期日 UTC+8上午9時27分00秒寫道: > There seems to be about five of them now. And the spam is on > comp.lang.c also. > Lynn Rick c. Hodgin's mother is died by cancer, god did a good job |
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