Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
333 views
in Technique[技术] by (71.8m points)

c++ - Is there a way to avoid implicit conversion to void*?

I'm using an API that accepts void* in certain functions. I frequently accidentally pass the wrong pointer type to the function, and of course it compiles fine, but doesn't work at runtime.

Is there a way to disable implicit conversion to void* for pointers to a certain class?

question from:https://stackoverflow.com/questions/68673443/is-there-a-way-to-avoid-implicit-conversion-to-void

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Is there any way to disable implicit conversion to void* for pointers to a certain class?

No, you can't prevent the implicit conversion, but you could wrap the API function(s) in proxy functions that checks types at compile time and approve/disapprove them there.

Example:

#include <iostream>
#include <string>
#include <type_traits>

void api(void* p) { // your original API
    std::cout << "void* " << p << '
';
}

template<class T>
void api_wrapper(T* p) { // your wrapper
    // let constness fail in the original api instead of in the static_assert:
    using type = std::remove_const_t<T>*;

    static_assert(
        // add your approved types here
        std::is_convertible_v<type, std::ostream*> ||
        std::is_convertible_v<type, std::string*>,
        "Not an approved type"
    );
    api(p);
}

int main() {
    std::string foo;
    api_wrapper(&std::cout);
    api_wrapper(&foo);
    //api_wrapper(&std::cin); // compile time error "Not an approved type"
}

If the set of pointer types that you would like to disapprove is very small, then instead of listing all the approved types in the static_assert, just list the disapproved types and adjust the boolean logic:

    static_assert(
        // add your disapproved types here
        not std::is_convertible_v<type, std::ostream*> &&
        not std::is_convertible_v<type, std::string*>,
        "Not an approved type"
    );

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...