C++:error C2228: left of ‘.str’ must have class/struct/union

Error C2228: Left of ‘. STR ‘must have class/struct/union

#include <string>
#include <iostream>
#include <vector>

using namespace std;

template <typename T>
class ValueBox {
private:
    T value;

private:

    template<typename U, 
        typename std::enable_if<std::is_class<U>::value && !std::is_same<U, string>::value, U>::type* = nullptr, 
        typename std::enable_if<!class_str<U>::ret, U>::type* = nullptr>
    std::string str(const T&) {
        cout << "1.---------------------" << endl;
        return "null";
    };

    template<typename U, 
        typename std::enable_if<std::is_class<U>::value && std::is_same<U, string>::value, U>::type* = nullptr>
    std::string str(const T&) {
        cout << "2.---------------------" << endl;
        return value;
    };

    template<typename U, 
        typename std::enable_if<std::is_class<U>::value && !std::is_same<U, string>::value, U>::type* = nullptr, 
        typename std::enable_if<class_str<U>::ret, U>::type* = nullptr>
    std::string str(const T&) {
        cout << "3.---------------------" << endl;
        return value.str();
    };

    template<typename U, 
        typename std::enable_if<!std::is_class<U>::value && std::is_arithmetic<U>::value, U>::type* = nullptr>
    std::string str(const T&) {
        cout << "4.---------------------" << endl;
        return std::to_string(value);
    };

public:
    ValueBox(const T& _value) : value(_value) {
    }

    const T& getValue() const {
        return value;
    };

    T& getValue() {
        return value;
    };

    std::string str() {
        return str<T>(value);
    };
};


int main() {
    ValueBox<string> s("sddds");
    cout << s.str() << endl;

    ValueBox<bool> j ( true);
    cout << j.str() << endl;

    ValueBox<int> i(100);
    cout << i.str() << endl;

    ValueBox<float> f ( 10.6f);
    cout << f.str() << endl;

    ValueBox<Box> b1 (Box());
    cout << b1.str() << endl;

    ValueBox<Bin> b2 (Bin());
    cout << b2.str() << endl;

    return 1;
}

The error was caused by the C++ compiler putting ValueBox< Box> b1 (Box()); In b1, Box() is regarded as the function definition, and Box() is regarded as the parameterless function with the return value of Box, except the function name is not defined at this time. There is a common name for the mistake: Most Vexing Parse
The modification methods are as follows:
1. Put Box on a separate line and initialize
Box b; // Box B () cannot be used; In this case, b is defined as a function
ValueBox< Box> b1 (b);
2. Wrap Box() in parentheses so that Box() is not treated as a function
ValueBox< Box> b1 ((Box()));
3. Use the uniform initialization syntax in C++11, that is, use {}
ValueBox< Box> b1 {Box()};
 

–Be alert for C++’s most vexing parse
Item 6. Be alert for C++’s most vexing parse
Effective STL note: Item 6–Be alert for C++’s most vexing parse

Read More: