"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: May 24 12:58PM -0700 For fun, I reproduced the following sequence: https://oeis.org/A059893 using a crude tree process: _________________________ #include <iostream> #include <cmath> namespace ct_rifc { unsigned long store(unsigned long x) { unsigned long i = 0; unsigned long v = 0; unsigned long tree_val = 0; for (i = 0; v != x; ++i) { unsigned long bit = ((x >> i) % 2); v += bit * std::pow(2, i); unsigned long child_left = tree_val * 2 + 1; unsigned long child_right = tree_val * 2 + 2; if (bit == 0) { // left //std::cout << "store left\n"; tree_val = child_left; } else { // right //std::cout << "store right\n"; tree_val = child_right; } //std::cout << "bit = " << bit << "\n"; //std::cout << "v = " << v << "\n"; //std::cout << "tree_val = " << tree_val << "\n\n"; } return tree_val / 2; } unsigned long load(unsigned long x) { x = x * 2; unsigned long x_tmp = x; unsigned long v = 0; unsigned long levels = 0; for (levels = 0; x_tmp != 0; ++levels) { x_tmp = (x_tmp - 1) / 2; } for (unsigned long i = 0; x != 0; ++i) { unsigned long parent = (x - 1) / 2; unsigned long child_left = parent * 2 + 1; unsigned long child_right = parent * 2 + 2; if (x == child_left) { // std::cout << "load left\n"; //v += 0 * std::pow(2, levels - i - 1); // mul by zero, nothing. } else { //std::cout << "load right\n"; v += 1 * std::pow(2, levels - i - 1); } x = parent; } return v; } void test() { for (unsigned long i = 0; i < 256; ++i) { unsigned long plaintext = i; unsigned long ciphertext = store(plaintext); unsigned long decrypted = load(ciphertext); //std::cout << "plaintext = " << plaintext << "\n"; //std::cout << "ciphertext = " << ciphertext << "\n"; //std::cout << "decrypted = " << decrypted << "\n"; std::cout << "(pt, ct, dt) = " << plaintext << ", " << ciphertext << ", " << decrypted << "\n"; //std::cout << "\n"; if (plaintext != decrypted) { std::cout << "FAILURE!\n"; break; } } } } int main() { { ct_rifc::test(); std::cout << "\n\nFIN!\n"; } //std::cin.get(); return 0; } _________________________ Can you compile and run this thing? Fwiw, here is a sample of the output: (pt, ct, dt) = 0, 0, 0 (pt, ct, dt) = 1, 1, 1 (pt, ct, dt) = 2, 2, 2 (pt, ct, dt) = 3, 3, 3 (pt, ct, dt) = 4, 4, 4 (pt, ct, dt) = 5, 6, 5 (pt, ct, dt) = 6, 5, 6 (pt, ct, dt) = 7, 7, 7 (pt, ct, dt) = 8, 8, 8 (pt, ct, dt) = 9, 12, 9 (pt, ct, dt) = 10, 10, 10 (pt, ct, dt) = 11, 14, 11 (pt, ct, dt) = 12, 9, 12 (pt, ct, dt) = 13, 13, 13 (pt, ct, dt) = 14, 11, 14 (pt, ct, dt) = 15, 15, 15 (pt, ct, dt) = 16, 16, 16 (pt, ct, dt) = 17, 24, 17 (pt, ct, dt) = 18, 20, 18 (pt, ct, dt) = 19, 28, 19 (pt, ct, dt) = 20, 18, 20 Notice the pattern in the ct (middle) column: 0, 1, 2, 3, 4, 6, 5, 7, 8, 12, 10, 14, 9, 13, 11, 15, ... |
Bob Langelaan <bobl0456@gmail.com>: May 24 08:00AM -0700 I came across the following code: typename Chain::Node * Chain::walk(Node * curr, int k){ if (k==0 || curr == NULL) return curr; else return walk(curr->next,k-1); } Can anyone explain what the purpose is for the keyword typename in the code above? Also, if it is a new feature, which I suspect, is it C++ 14, C++ 17 or C++ 20? Thanks! |
Sam <sam@email-scan.com>: May 24 11:31AM -0400 Bob Langelaan writes: > } > Can anyone explain what the purpose is for the keyword typename in the code > above? typename is really just an alias for "class". > Also, if it is a new feature, which I suspect, is it C++ 14, C++ 17 or C++ > 20? You could always use typename as an alias for "class". And, like "class" itself, in this context, it's mostly superfluous. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 24 05:35PM +0200 On 24.05.2020 17:00, Bob Langelaan wrote: > } > Can anyone explain what the purpose is for the keyword typename in the code above? > Also, if it is a new feature, which I suspect, is it C++ 14, C++ 17 or C++ 20? You can see from the recursive "let's get some UB!" C++ implementation of a linear complexity algorithm, that it's written by an incompetent. So that's essentially the answer. If this is actually outside any template then I doubt that it's valid. - Alf |
Bob Langelaan <bobl0456@gmail.com>: May 24 09:13AM -0700 On Sunday, May 24, 2020 at 8:35:18 AM UTC-7, Alf P. Steinbach wrote: > So that's essentially the answer. > If this is actually outside any template then I doubt that it's valid. > - Alf This code compiles and is definitely not inside a template definition. Some of the code written by the same individual seems reasonably competent such as: void list_test( string msg, Node *actual, initializer_list<int> expect ) { vector<int> act = to_vector( actual ); vector<int> exp; cout << msg << ": "; print( actual ); for( auto elem : expect ) { exp.push_back(elem); } if( act == exp ) return; cerr << "*ERROR* " << vectorStr(act) << " != (expected) " << vectorStr(exp) << "\n"; } |
Bob Langelaan <bobl0456@gmail.com>: May 24 09:18AM -0700 On Sunday, May 24, 2020 at 8:32:05 AM UTC-7, Sam wrote: > > 20? > You could always use typename as an alias for "class". And, like "class" > itself, in this context, it's mostly superfluous. I knew that in a template definition, typename can usually be replaced by class. So I guess I am asking what is the purpose of prefixing the return type of a function with the keyword typename (or class)? |
Bo Persson <bo@bo-persson.se>: May 24 06:30PM +0200 On 2020-05-24 at 18:18, Bob Langelaan wrote: >> You could always use typename as an alias for "class". And, like "class" >> itself, in this context, it's mostly superfluous. > I knew that in a template definition, typename can usually be replaced by class. So I guess I am asking what is the purpose of prefixing the return type of a function with the keyword typename (or class)? There is no purpose, unless Chain is a nasty #define for a template. However, the syntax probably allows for a redundant typename even when it is not really needed. In other cases 'typename' is requires even in places where nothing but a type is possible. :-) Some effort has been done to try to sort this out http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0634r1.html but the work is far from complete. Bo Persson |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 24 06:44PM +0200 On 24.05.2020 18:13, Bob Langelaan wrote: > cerr << "*ERROR* " << vectorStr(act) << " != (expected) " > << vectorStr(exp) << "\n"; > } My eyes. - Alf |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 24 08:07PM +0100 On Sun, 24 May 2020 09:18:22 -0700 (PDT) > I knew that in a template definition, typename can usually be replaced > by class. So I guess I am asking what is the purpose of prefixing the > return type of a function with the keyword typename (or class)? 'typename' could not necessarily be replaced by 'class' here. In this usage the 'typename' keyword indicates that Node is a nested (dependent) type defined in class Chain, which might for example be defined in that class by a typedef or the using keyword. Employing 'class' in place of 'typename' would indicate that Node is a nested class or struct type defined within a class Chain or a Chain namespace. Typical usage of 'typename' here would be if 'walk' is a method of a template class having Chain as a template parameter. It would indicate that Chain::Node is a dependant type of Chain. If there is no template definition involved here, then assuming Chain::Node is indeed a type alias, in C++11 onwards 'typename' is harmless but redundant. With C++98/03 I think it would be an error. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: May 24 08:15PM +0100 On Sun, 24 May 2020 20:07:56 +0100 > class or struct type defined within a class Chain or a Chain namespace. > Typical usage of 'typename' here would be if 'walk' is a method of a > template class having Chain as a template parameter. By the way, if that were the case here then I would expect compilation to fail because the type of argument 'curr' is not qualified as a dependent type of Chain. |
"Öö Tiib" <ootiib@hot.ee>: May 23 05:19PM -0700 On Sunday, 24 May 2020 01:39:47 UTC+3, Sam wrote: > having the "rvalue" overload of func() called). > As pictured, x *&& doesn't work. Returning either "x &&*" or "x &&" is ill- > formed; is this even possible? I do not understand what you try to do but "std::move(Y)->func();" will call rvalue-qualified version of func() of lvalue Y. |
"Öö Tiib" <ootiib@hot.ee>: May 23 05:28PM -0700 On Sunday, 24 May 2020 03:19:17 UTC+3, Öö Tiib wrote: > I do not understand what you try to do but "std::move(Y)->func();" will > call rvalue-qualified version of func() of lvalue Y. Nah, just leave it that I do not understand what you try to do. IOW these operators, funcs, and rvalues ... each seem totally pointless struggle to do something purpose of what I do not get. |
Sam <sam@email-scan.com>: May 24 12:07AM -0400 Öö Tiib writes: > On Sunday, 24 May 2020 03:19:17 UTC+3, Öö Tiib wrote: > > I do not understand what you try to do but "std::move(Y)->func();" will > > call rvalue-qualified version of func() of lvalue Y. No, it does not do that, I'm afraid. > Nah, just leave it that I do not understand what you try to do. IOW > these operators, funcs, and rvalues ... each seem totally pointless > struggle to do something purpose of what I do not get. That's ok, maybe someone else will. But thanks for trying. |
"Öö Tiib" <ootiib@hot.ee>: May 24 03:42AM -0700 On Sunday, 24 May 2020 07:07:56 UTC+3, Sam wrote: > > these operators, funcs, and rvalues ... each seem totally pointless > > struggle to do something purpose of what I do not get. > That's ok, maybe someone else will. But thanks for trying. That is ... unlikely. Your pointer-like object itself being temporary and pointed at object being temporary are unrelated and your attempt to conflate these will likely confuse anyone, yourself included few weeks later. Other confusing things ... * The operator-> is not meant for returning references. It must return pointers or (possibly references to) things that are capable to become a pointer through implicit chain of operator-> calls. On any case at end of the chain has to be a raw pointer. * Pointers (irrelevant if raw or smart) to whatever references (rvalue or lvalue) do not make sense in C++ language. Reference is alias of actual object, not separate object. * There is unary operator* that is meant for returning references and so is always overloaded at same time with -> but your code does not. . We can return rvalue references to pointed at object like ...: x && getX() { return std::move(*ptr); } ... but there we should also deeply consider the consequences if it is safe and sensible thing to do. If you want to make copyable and reseatable but not nullable pointers then std::reference_wrapper is already what can be done in C++. |
Sam <sam@email-scan.com>: May 24 08:45AM -0400 Öö Tiib writes: > Your pointer-like object itself being temporary and pointed at object > being temporary are unrelated and your attempt to conflate these will > likely confuse anyone, yourself included few weeks later. Actually, the confusion already exists. A frequently suggested idiom for avoiding dangling references, when trying to avoid unnecessary copies: class apple { // .. something }; class basket { private: apple fuji; public: const apple &getApple() const & { return fuji; } apple getApple() && { return fuji; } }; This generally fixes prvalue-caused dangling references. However this fails with std::shared_ptr: std::shared_ptr<basket> get_current_basket(); const auto &lunch=get_current_basket()->getApple(); You can do this with operator*, but not operator->. I can get the results I want with the * operator: x &&operator*() && This seems to work as intended: x X; y Y{&X}; (*Y).func(); (*y{&X}).func(); This ends up calling the appropriate ref-qualified overload of x, depending upon whether an instance of y, that implements the overloaded * operator, is an lvalue or an rvalue. However an operator-> cannot return x &&*, unfortunately, because that would be ill-formed. |
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