简体   繁体   中英

std::string not updated with = operator

So here's a puzzle for some C++ developers here.

I have a custom String class I'm working with that's supposed to teach me how to get comfortable with classes and a few other C++ features and this class has a value property it uses to keep track of its primitive value (which is a std::string ).

But here's a problem, I have define multiple methods for creating an object of this class. 2 of which I understand perfectly:

String stringA = "Hello, World!";
String stringB = String("Hello, World!");

But the last one is a bit tricky as it should be able to work with an infinite set of arguments (theoretically).

String stringC = String("Hello,", ' ', "World!");

But when I access the primitive values of these strings, the last one seems to bug out and return (to the best of my debugging efforts) nothing, garbled text or just part of the arguments given.

stringA.valueOf(); // -> Hello, World!
stringB.valueOf(); // -> Hello, World!
stringC.valueOf(); // -> Hello,

Now, this has been a challenge I've really struggled with especially as a JavaScript developer diving into C++. I know the two languages are fundamentally different, but I figure that logically there should be some features of the former that can somewhat be applied to the latter (such as variadic arguments).

For anyone who can help with this and explain to me what I'm missing (or why my code sucks), you're an absolute champ. Great going for you.

#include <iostream>

/* Let's assume there's a `stringify` function that converts any value to `std::string` */
class String {
    private:
        std::string value;

    public:
        template <typename data>
        String(data arg) { this -> value += arg; }

        template <typename data, typename... argumentsData>
        String(data arg, argumentsData... args) {
            this -> value += arg;
            String(args...);
        }

        template <typename data>
        String operator =(data arg) { return String(this -> value = arg); }

        std::string valueOf() const { return this -> value; }
};

int main() {
    String stringA = "Hello, World!";
    String stringB = String("Hello, World!");
    String stringC = String("Hello,", ' ', "World!");

    std::cout << "String A: " << stringA.valueOf() << std::endl;
    std::cout << "String B: " << stringB.valueOf() << std::endl;
    std::cout << "String C: " << stringC.valueOf() << std::endl;

    return 0;
}

In your constructor

template <typename data, typename... argumentsData>
String(data arg, argumentsData... args) {
    this -> value += arg;
    String(args...);
}

This line: String(args...); creates and discards a temporary String , which doesn't affect the state of the original object.

Instead of trying to solve this with recursion, I recommend using fold expressions:

template <typename ...P>
String(const P &... params) // Passing by const reference is purely an optimization.
{
    ((value += params) , ...);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM