Home > Software engineering >  error: no match for 'operator =' (operand types are 'long double' and 'std:
error: no match for 'operator =' (operand types are 'long double' and 'std:

Time:10-14

I need to read values from a tuple that could be any datatype and then add them if they are numbers, or concatenate them if they are castable as strings.

tuple<int32_t, bool, string, float, const char*, char, int> t{10, true, "Modern", 2.3f, "C  ", 'e', 13}; // Example Tuple

So I thought a template would be the way to go but I get a compilation error even though it should not be possible for the situation to happen where a number and a const char* are added.

no match for 'operator =' (operand types are 'long double' and 'std::__cxx11::basic_string<char>')
   22 |         numericSum  = tupleValue;
      |         ~~~~~~~~~~~^~~~~~~~~~~~~
error:   in evaluation of 'operator =(long double, const char*)'

So what could be a way to modify my code to work around this problem? Is there an easy way to detect chars and strings similarly to is_arithmetic?

// Based on the datatype of the tupleValue, we either add, concatenate or ignore the value
template<typename T>
void interact_with_tuple(T tupleValue, long double &numericSum, string &stringConcatenation, int &argumentsIgnored){
    // Check for chars
    if (is_convertible<T*, string>::value){
        stringConcatenation  = tupleValue;
    }
    // Check for strings and char pointers
    else if (is_convertible<T, string>::value){
        stringConcatenation  = tupleValue;
    }
    // Check for integers and floating point numbers but exclude bools
    else if (is_arithmetic<T>::value && !is_same<T, bool>::value){
        numericSum  = tupleValue;
    }   
    else{
        argumentsIgnored  = 1;
    }

    cout << tupleValue << endl;
}

Code from main function:

int main(){
    tuple<int32_t, bool, string, float, int> t{10, true, "Modern", 2.3f, 13}; // Example Tuple

    long double NumericSum = 0.0;
    string stringConcatenation = "";
    int argumentsIgnored = 0; // Im going to assume I don't need a long long for this

    // Iterate through Tuple
    apply([&](auto&&... args){((interact_with_tuple(args, NumericSum, stringConcatenation, argumentsIgnored)), ...);}, t); 

    cout << "NumericSum: " << NumericSum << endl;
    cout << "stringConcatenation: " << stringConcatenation << endl;
    cout << "argumentsIgnored: " << argumentsIgnored << endl;
}

CodePudding user response:

You can use the C 17' is new compile-time conditional if constexpr. It will compile only the chunk that you need and discard the rest.

if constexpr (std::is_convertible<T*, std::string>::value){
    stringConcatenation  = tupleValue;
}
// Check for strings and char pointers
else if constexpr (std::is_convertible<T, std::string>::value){
    stringConcatenation  = tupleValue;
}
// Check for integers and floating point numbers but exclude bools
else if constexpr (std::is_arithmetic<T>::value && !std::is_same<T, bool>::value){
    numericSum  = tupleValue;
}   
else{
    argumentsIgnored  = 1;
}

Live demo: https://godbolt.org/z/rff88hM8r

  •  Tags:  
  • c
  • Related