Why does code line give an error even though it never runs?

137 views Asked by At

I ran into a problem while making another program where there was an error even though the line with the error was never going to run in the first place.

Down below, I have made a simpler version of the program where the same problem occurs.

To summarize the program, I have a class with a constructer that uses ellipsis. When looping through the arguments, I check if each of them are an std::string (I know it's probably inefficient to check each iteration of the loop). If they are std::string, then const char* will be passed to va_arg(), and if not, T will be passed to va_arg(). I did this because I couldn't pass std::string into va_arg(), so I had to do this instead.

The error I get is:

 '<function-style-case>': cannot convert from 'const char*' to 'T'

Btw, I have commented out the code where T was int and where T was std::string. Only the part where I set T to be double has stayed uncommented.

#include <iostream>
#include <cstdarg>



template<typename T>
class TestClass {
private:
    T arr[10];

public:
    TestClass(int count, ...) {
        va_list args;
        va_start(args, count);

        for (size_t i = 0; i < count; i++) {
            if (typeid(T) == typeid(std::string))
                arr[i] = T(va_arg(args, const char*)); // This is what causes the error
            else
                arr[i] = va_arg(args, T);
        }
    }
};


int main()
{
    /*int int1 = 5;
    int int2 = 7;
    int int3 = 1;
    TestClass<int> intClass(3,
        int1,
        int2,
        int3
    );*/

    /*std::string str1 = "John";
    std::string str2 = "Kim";
    std::string str3 = "Harry";
    TestClass<std::string> stringClass(3,
        str1,
        str2,
        str3
    );*/

    double d1 = 5.12;
    double d2 = 7.56;
    double d3 = 1.89;
    TestClass<double> doubleClass(3,
        d1,
        d2,
        d3
    );
}

The code runs perfectly fine when I set T to be int or std::string. However when I set T to be double, the code just won't run. I don't understand this, because the if statement that checks whether or not T is std::string will never be true since T is double. So why does the error occur when the code that gives the error will never run in the first place?

I haven't been able to find anyone with the same problem, and I don't know how to fix it. I would be so happy if you could help me with this issue. Thanks a lot in advance.

1

There are 1 answers

1
user12002570 On BEST ANSWER

Note that you should use variadic templates instead of C variadics(aks variadic functions).


Now coming to the problem, you can replace the use of if with constexpr if and then use std::is_same as shown below as if constexpr is evaluated at compile time, whereas if is not.

template<typename T>
class TestClass {
private:
    T arr[10];

public:
    TestClass(int count, ...) {
        va_list args;
        va_start(args, count);

        for (size_t i = 0; i < count; i++) { 
//----------vvvvvvvvvvvv------vvvvvvvvvv----------------------->use constexpr if and std::is_same
            if constexpr(std::is_same_v<T, std::string>)  
                arr[i] = T(va_arg(args, const char*)); // compiles now
            else
                arr[i] = va_arg(args, T);
        }
    }
};

Working demo