Forum Replies Created

Viewing 15 posts - 46 through 60 (of 349 total)
  • Author
    Posts
  • in reply to: My First Queston #632622
    RainerRainer
    Keymaster
        Up
        0
        Down
        ::

        std::cout << '\n';
        
            std::atomic<std::shared_ptr<std::string>> sharString(
                std::make_shared<std::string>("Zero"));
            
            std::thread t1([&sharString]{ 
                sharString.store(std::make_shared<std::string>(*sharString.load() + "One")); 
            });
            std::thread t2([&sharString]{ 
                sharString.store(std::make_shared<std::string>(*sharString.load() + "Two")); 
            });
            std::thread t3([&sharString]{ 
                sharString.store(std::make_shared<std::string>(*sharString.load() +"Three"));
            });
            std::thread t4([&sharString]{ 
                sharString.store(std::make_shared<std::string>(*sharString.load() +"Four")); 
            });
            std::thread t5([&sharString]{ 
                sharString.store(std::make_shared<std::string>(*sharString.load() +"Five")); 
            });
        
        in reply to: Function Hiding vs Overriding #632567
        RainerRainer
        Keymaster
            Up
            0
            Down
            ::

            When you apply multiple inheritance, the base classes should be orthogonal. Said that, this example is crazy because both base classes provide a pure virtual member function display. I cannot find anything in the C++ standard, but I assume that the program is correct. You essentially override both pure virtual member functions.

            I modified the program and added a display function to Derived:

            #include <iostream>
            
            class GrandGrandParent
            {
            public:
                virtual void display() = 0;
            };
            
            class GrandParent : public GrandGrandParent
            {
            };
            
            class human
            {
            public:
                virtual void display() = 0;
            };
            
            class Parent : public GrandParent, public human
            {
            public:
                // Both parent class has method with same name display. We have overriden the function in this class.
                // Which function is getting overriden ? Can you please provide some more insight how static(Parent*P) and dynamic type(new Derived()) working here
                void display() override
                {
                    std::cout << "Derived";
                }
            };
            
            class Derived : public Parent
            {
                void display() override {
                    std::cout << "Derived display";
                }
            };
            
            int main()
            {
                Parent *p = new Derived();
                p->display(); // Derived
            }
            

            The static type of Parent *p = new Derived() is Parent but the dynamic Derived. The static type determines the access specifiers. Consequentially, display in Derived can be private.

            in reply to: Deriving privately #632544
            RainerRainer
            Keymaster
                Up
                0
                Down
                ::

                Here is a pictorial representation:

                in reply to: reinterpret cast – undefined behavior? #632081
                RainerRainer
                Keymaster
                    Up
                    0
                    Down
                    ::

                    The use-cases for a reinterpret_cast are pretty limited:

                    • A pointer into a pointer
                    • An integral into a pointer
                    • A pointer into an integral

                    The reinterpret_cast guarantees that the conversion to and from a pointer returns the same value.

                    All other casts are undefined behavior.

                     

                    RainerRainer
                    Keymaster
                        Up
                        0
                        Down
                        ::

                        Interestingly, when you use a constexpr function in between, the GCC and MSVC apply the necessary conversions: https://godbolt.org/z/d3jM6oaeP

                        template <double d>
                        auto acceptOnlyDouble() {
                            return d;
                        }
                        
                        constexpr double ToDouble(double param) {
                            return param;
                        }
                        
                        int main() {
                            const auto xf_double88 = acceptOnlyDouble<-5.123456788>();
                            const auto xf_double89 = acceptOnlyDouble<-5.123456789>();
                            const auto xf_float = acceptOnlyDouble<ToDouble(-9.48f)>();
                            const auto xf_long = acceptOnlyDouble<ToDouble(-20L)>();
                        }
                        

                        Finally, I asked Jorg Brown, author of the proposal P1714: NTTP are incomplete without float, double, and long double! (Revision 1).

                        He said: Anyway, to answer your question, I think MSVC is doing the right thing here. I’ll check with a friend to be sure…

                        in reply to: Unified lookup rules for std algorithms #632026
                        RainerRainer
                        Keymaster
                            Up
                            0
                            Down
                            ::

                            The issue that you can implement the begin operator as a member or as a free function. Calling the begin iterator fails when you assume a free function, but you have implemented it as a member function. The same goes the other way around. On the contrary, std::ranges::begin(cont) will find a free function and a member function.

                            in reply to: Why the two alternatives for a given view #632025
                            RainerRainer
                            Keymaster
                                Up
                                1
                                Down
                                ::

                                Strictly speaking, the functions in the namespace std::views like std::views::values are range adaptors, and the types in the namespace std::ranges like std::ranges::values_view are views. A range adaptor range | std::views::values operates on a range and returns a view, but a view gets a range as argument: std::ranges::values_view{range}.

                                Here is a comparison between std::views::drop and std::ranges::drop_view:

                                const auto numbers = {1, 2, 3, 4, 5};
                                
                                auto firstThree = numbers | std::views::drop(3);
                                std::ranges::drop_view firstThree{numbers, 3};
                                auto firstThree = std::views::drop(3)(numbers);
                                

                                 

                                 

                                RainerRainer
                                Keymaster
                                    Up
                                    1
                                    Down
                                    ::

                                    Honestly, it’s pretty complicated to understand your problem. I suggest that you create the corresponding files and put it together to reproduce this error. This means to show how we can reproduce your compilation error. Make your program as concise as possible to trigger the error.

                                    RainerRainer
                                    Keymaster
                                        Up
                                        0
                                        Down
                                        ::

                                        Now, I got it. I’m not sure which compiler is correct. If the GCC is correct, it behaves differently to integral non-type template parameters.

                                        RainerRainer
                                        Keymaster
                                            Up
                                            0
                                            Down
                                            ::

                                            I don’t see your point about GCC. I only find it unintuitive when I compare the example with double and int as non-type template parameter.

                                            RainerRainer
                                            Keymaster
                                                Up
                                                0
                                                Down
                                                ::

                                                My first impression was also that GCC is correct. Only GCC fully supports this feature: https://en.cppreference.com/w/cpp/compiler_support#cpp20. Said that, the following program is correct:

                                                #include <iostream>
                                                
                                                template< int d >
                                                auto acceptOnlyInt()
                                                {
                                                    return d;
                                                }
                                                
                                                int main()
                                                {
                                                    //function template accepting only int
                                                    const auto d1 = acceptOnlyInt< 5 >();
                                                    const auto d2 = acceptOnlyInt< 9u >();
                                                    const auto d3 = acceptOnlyInt< 16 >();
                                                    const auto d4 = acceptOnlyInt< 20L >();
                                                }
                                                

                                                GCC, Clang, and the MSVC Compiler accept it: https://godbolt.org/z/ofrqxYd31.

                                                I still assume that GCC is correct, but it behaves strange compared with my int version.

                                                in reply to: Compile time programming use cases #631575
                                                RainerRainer
                                                Keymaster
                                                    Up
                                                    1
                                                    Down
                                                    ::

                                                    The format library in C++20 (std::format, std::format_to, and std::format_to_n) is a nice example of compile time parsing. This means that it is pretty fast, and you get a parse error at compile-time.

                                                    When your format string is not constexpr, you have to use std::vformat or std::vformat_to. They throw a runtime error in case.

                                                    RainerRainer
                                                    Keymaster
                                                        Up
                                                        1
                                                        Down
                                                        ::

                                                        Compilation is not part of the C++ standard. Compilation is a question of your tool chain: make, CMake, Visual Studio, … . Usually, you compile each source file separately using the same flags and link them together in one long line. This has the advantage that you only have to recompile one file if that is necessary.

                                                        Assume that you changed main.cpp.

                                                        g++ -c main.cpp                      // (1)
                                                        
                                                        g++ -c source.cpp
                                                        
                                                        g++ main.o source.o -o mainsource    // (2)
                                                        
                                                        Are these equivalent to:
                                                        
                                                        g++ main.cpp source.cpp -o mainsource // (3)
                                                        

                                                        In the first case, you have to recompile main.cpp and link the executable, but in the second case, you also have to recompile source.cpp. This means that the first case is significantly faster.

                                                        in reply to: Wrong content in Blog #631414
                                                        RainerRainer
                                                        Keymaster
                                                            Up
                                                            1
                                                            Down
                                                            ::

                                                            You are right. I will fix it. I recognized my error while I was preparing the C++20 mentoring.

                                                            RainerRainer
                                                            Keymaster
                                                                Up
                                                                0
                                                                Down
                                                                ::

                                                                The issue is that you must synchronize the static member on the class level. When you put its modification inside a member function, you synchronize it on the instance level.

                                                              Viewing 15 posts - 46 through 60 (of 349 total)