Forum Replies Created

Viewing 15 posts - 316 through 330 (of 349 total)
  • Author
    Posts
  • in reply to: const member functions #10096
    RainerRainer
    Keymaster
        Up
        0
        Down
        ::

        Let me clarify this.

        struct MyStruct {
            void constMemberFunction() const {}
            void nonConstMemberFunction() {}
        };
        
        int main() {
        
            const MyStruct myConstStruct;
            MyStruct myNonConstStruct;
        
            myConstStruct.constMemberFunction();
            myNonConstStruct.constMemberFunction();
        
            myConstStruct.nonConstMemberFunction();  // Error: discards const qualifier
            myNonConstStruct.nonConstMemberFunction();
        
        }
        

        A const instance can invoke only const member functions.

        A non-const instance can invoke const and non-const member functions.

         

         

        in reply to: Data generated at compile time #10079
        RainerRainer
        Keymaster
            Up
            0
            Down
            ::

            When you need your vector at run time, you cannot use constexpr. This idea of a constexpr vector is that you do your operations at compile time. Additionally, when you need 10’000 such vectors, there is no way to overcome this. A std::vector needs on my platform 24 bytes more than a C-Array or a std::array: https://www.modernescpp.com/index.php/c-core-guidelines-the-standard-library

            The only solution I see for your vectors is to share data. This is possible if the vectors are immutable.

            RainerRainer
            Keymaster
                Up
                0
                Down
                ::

                Very good poin: decltype does not evaluate its value. => decltype is a so-called unevaluated operand: https://humanreadablemag.com/issues/0/articles/what-are-unevaluated-operands-in-c

                in reply to: dynamic_cast #10066
                RainerRainer
                Keymaster
                    Up
                    0
                    Down
                    ::

                    I assume, you mean to following program:

                    // dynamic_cast
                    #include <iostream>
                    #include <exception>
                    using namespace std;
                    
                    class Base { virtual void dummy() {} };
                    class Derived: public Base { int a; };
                    
                    int main () {
                      try {
                        Base * pba = new Derived;
                        Base * pbb = new Base;
                        Derived * pd;
                    
                        pd = dynamic_cast<Derived*>(pba);
                        if (pd==0) cout << "Null pointer on first type-cast.\n";
                    
                        pd = dynamic_cast<Derived*>(pbb);
                        if (pd==0) cout << "Null pointer on second type-cast.\n";
                    
                      } catch (exception& e) {cout << "Exception: " << e.what();}
                      return 0;
                    }
                    

                    In this example, the downcast pd = dynamic_cast<Derived*>(pba); works, because pba is a pointer to Derived and Base is a polymorphic type. This does not hold for the second example. pbb is a Pointer to Base and not to Derived.

                    RainerRainer
                    Keymaster
                        Up
                        0
                        Down
                        ::
                        1. This is tricky. With C++11, a constexpr function is const ( https://godbolt.org/z/7bjYMYP8Y). This does not hold for C++14: a constexpr function in not const. Consequentially, you have to declare getVal as const to use it with a constexpr object.
                        2. decltype(mDoble2) is const MyDouble, but MyDouble is not const. This works: static_assert(std::is_same_v< decltype(mDoble2), const MyDouble >, “Types not the same: mDoble3 and MyDouble”);
                        3. mDoble3 is not const
                        in reply to: Data generated at compile time #10051
                        RainerRainer
                        Keymaster
                            Up
                            0
                            Down
                            ::

                            Here is a valid example:

                            #include <algorithm>
                            #include <iostream>
                            #include <vector>
                            
                            constexpr int maxElement() {
                                std::vector myVec = {1, 2, 4, 3};
                                std::sort(myVec.begin(), myVec.end());
                                return myVec.back();
                            }
                            int main() {
                            
                                std::cout <<  '\n';
                            
                                constexpr int maxValue = maxElement();
                                std::cout << "maxValue: " << maxValue << '\n';
                            
                                std::cout << '\n';
                            
                            }

                            As you can see from the Compiler Explorer output (https://godbolt.org/z/bcsWrbG85), only the maxElement is left from the vector.

                            in reply to: Ordered List are not shown correctly #10050
                            RainerRainer
                            Keymaster
                                Up
                                0
                                Down
                                ::

                                Now, it should work. I overwrote the css configuation of my theme for bbpress.

                                in reply to: Initialization Exercise: another implementation #10029
                                RainerRainer
                                Keymaster
                                    Up
                                    0
                                    Down
                                    ::

                                    Since C++17, the C++ compiler  can automatically deduce the template arguments for class templates:

                                    std::vector<int> myVec{1, 2, 3};

                                    becomes, therefore:

                                    std::vector myVec{1, 2, 3};
                                    in reply to: auto versus decltype #9993
                                    RainerRainer
                                    Keymaster
                                        Up
                                        1
                                        Down
                                        ::

                                        auto and decltype serve similar purposes: deduce the type of an expression. auto let you declare a variable with a specific type, and decltype extracts the type of a variable.

                                        • auto (auto i = 5)
                                          • The type of a expression will be deduced from an initializer
                                          • Avoids long verbose type specification when defining a variable
                                          • auto type deduction is essentially template type deduction
                                          • Returns the decayed type (https://en.cppreference.com/w/cpp/types/decay)
                                        • decltype (decltype(5))
                                          • Determines the declared type of an entitiy or an expression
                                          • Returns the exact type

                                        I consider auto to be a purely simplifying feature whereas the primary purpose of decltype is to enable sophisticated metaprogramming in foundation libraries. They are however very closely related when looked at from a language-technical point of use. (From HOPL20 4.2.1, Bjarne Stroustrup).

                                         

                                        in reply to: Overusing auto #9971
                                        RainerRainer
                                        Keymaster
                                            Up
                                            0
                                            Down
                                            ::
                                            auto firstVar = 1.2; // double
                                            
                                            auto secondVar = 1.2f // float
                                            

                                            The compiler deduces the type of the initializer. In the first case, 1.2 is a double literal; in the second case, 1.2f is a float literal. Therefore, firstVar becomes a double, and secondVar becomes a float. I see no issue with type promotion.

                                             

                                            in reply to: Assembly Basics #9966
                                            RainerRainer
                                            Keymaster
                                                Up
                                                0
                                                Down
                                                ::

                                                Honestly, I’m not an assembler expert, but my knowledge is most of the time sufficient to study the output of the Compiler Explorer. My assembler experience goes back into the 90ths and is based on a predecessor of the Motorola 68000 family.

                                                Most of the time, there is one book suggested, when it comes to a deeper understanding of assembler: the dragon book. Have a look her: https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools.

                                                in reply to: Initialization of Raw Strings Literals #9963
                                                RainerRainer
                                                Keymaster
                                                    Up
                                                    0
                                                    Down
                                                    ::

                                                    There is no difference. The compiler explorer proofs it. Don’t use C++ Insights for your analysis. C++ Insights just show the first transformations of your compiler, before any opimization kicks in.

                                                    in reply to: Specifying the used C++ Standard #9961
                                                    RainerRainer
                                                    Keymaster
                                                        Up
                                                        0
                                                        Down
                                                        ::

                                                        The answer depends on the version of your compiler. Each compiler uses a default C++ standard for code generation.

                                                        • GCC

                                                        For gcc, the following holds:

                                                        • 5.5.0: C++11 is the default for code generation
                                                        • 6.1.0: C++14 is the default for code generation
                                                        • 11.1.0: C++17 is the default for code generation

                                                        When you want to use C++20 with the g++ Version 11.1.0, you have to specify the standard: g++ -std=c++20.

                                                        • Clang

                                                        The gcc flags work for clang++.

                                                        • MSVC

                                                        With the MSVC compiler, I always use the following flag: /std:c++latest, but you can also specify /std:c++11, /std:c++14, and so on.

                                                        in reply to: Function by reference #9951
                                                        RainerRainer
                                                        Keymaster
                                                            Up
                                                            0
                                                            Down
                                                            ::

                                                            So far, I have no use-case in mind. This example only serves as an example to show you the difference. The following line without the reference gives you a pointer.

                                                            auto& myFuncRef = func;
                                                            

                                                             

                                                             

                                                            in reply to: Overusing auto #9949
                                                            RainerRainer
                                                            Keymaster
                                                                Up
                                                                0
                                                                Down
                                                                ::

                                                                Very good question. Here are my thoughts.

                                                                For performance and readability reasons, I prefer the following syntax.

                                                                std::vector<int> myFunc() {
                                                                
                                                                   return {1, 2, 3};
                                                                
                                                                }
                                                                

                                                                The return value is a temporary. Therefore, return value optimization (RVO, https://www.modernescpp.com/index.php/cpp17-core) kicks in, and the vector is directly created in the caller:

                                                                std::vector<int> result = myFunc();

                                                                Honestly, I’m not sure if I would use in this case auto or std::vector<int> for result.

                                                                May decision depends on one point. Do I have a meaningful name for result or not? If yes, I prefer auto:

                                                                auto userIDs = myFunc();
                                                                

                                                                The readability of your program should not be based on type information, but on good names. auto enforces this is some way. types have no semantic. A std::vector<int> can be anything.

                                                              Viewing 15 posts - 316 through 330 (of 349 total)