简体   繁体   中英

How to ouput diagnostic messages during compiling time to tell which overloaded function was called

For example, I have overloaded functions, f() , they are defined as

    struct Test {
        int i = 1;
        Test(double d) : i (d){}
    };

    struct MyClass {
        int f(double d) {
            cout << "parent\n";
            return d + 3 ; }
    };

    struct Child : public MyClass {
        using MyClass::f; // if we comment out this line, the output will be different
        double f(Test t) {
            cout << "child\n";
            return t.i * 9;
        }
    };

    int main() {
        Child c;
        std:: cout << c.f(1.0) << std::endl;
    }

The function f in Child class overloaded the function in parent. How can we generate diagnostic information during compiling time, such that we know which function is chosen by the compiler for cf(1.0) ?

Note that if I remove the line using MyClass:f; , the output will be different but there are no error for compiling.

Update:

Based on @PW 's answer, there are two ways to modify the existing class to use template instantiation to output the static assertion,

template <typename T>
struct ConditionalFalse {
    static constexpr bool value = false;
};

struct Test {
    int i = 1;
    Test(double d) : i (d){}
};
struct MyClass {
    template<typename T>
    int f(double i) {
        static_assert(ConditionalFalse<T>::value, "Parent");
        return i + 3 ; }
};

struct Child : public MyClass {
    using MyClass::f;
    template<typename T>
    double f(Test t) {
        static_assert(ConditionalFalse<T>::value, "Child");
        return t.i * 9;
    }
};

template<typename T>
struct MyClassT {
    int f(double i) {
        static_assert(ConditionalFalse<T>::value, "ParentT");
        return i + 3 ; }
};

template<typename T>
struct ChildT : public MyClassT<T> {
    using MyClassT<T>::f;
    double f(Test t) {
        static_assert(ConditionalFalse<T>::value, "ChildT");
        return t.i * 9;
    }
};

int main() {
    Child c;
    std:: cout << c.f<int>(1.0) << std::endl;

    ChildT<int> ct;
    std:: cout << ct.f(1.0) << std::endl;
}

I am still wondering if this is possible without modifying the class or the member function to be a template?

A simple static_assert(false_condition, "...") would fail at compile time always. So you need something that happens at compile-time and is still dependent on something else. You can do this if your MyClass and Child were templates.

You will also need a dependent expression, and so you can use a helper struct to get something that will be type-dependent.

Now your code will look like this:

#include<iostream>

template <typename T>
struct ConditionalFalse { static constexpr bool value = false; };

struct Test {
    int i = 1;
    Test(double d) : i (d){}
};

template <typename T>
struct MyClass {
    int f(double d) {
        static_assert(ConditionalFalse<T>::value, "The Parent function is called\n");        
        return d + 3 ; }
};

template <typename T>
struct Child : public MyClass<T> {
    using MyClass<T>::f; // if we comment out this line, the output will be different
    double f(Test t) {
    static_assert(ConditionalFalse<T>::value, "The Child function is called\n");        
        return t.i * 9;
    }
};

int main() {
    Child<int> c; //The template parameter doesn't matter

    std::cout << c.f(1.0) << std::endl;
}

Depending on whether using MyClass<T>::f; is commented or not you will get different assertions.

If it is not commented, you will get:

error: static assertion failed: The Parent function is called
         static_assert(ConditionalFalse<T>::value, "The Parent function is called\n");
                       ^~~~~~~~~~~~~~~~~~~

If it is commented, you will get:

<source>:22:19: error: static assertion failed: The Child function is called
     static_assert(ConditionalFalse<T>::value, "The Child function is called\n");
                   ^~~~~~~~~~~~~~~~~~~

You can see it live here .

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