std::is_member_function_pointer does not compile if false












9















What I am looking for: I have a templated class and want to call a function if the class has the wanted function, something like:



template<class T> do_something() {
if constexpr (std::is_member_function_pointer<decltype(&T::x)>::value) {
this->_t->x(); // _t is type of T*
}
}


What happens: The compiler does not compile if T does not bring the function. Small example:



#include <type_traits>
#include <iostream>

class Foo {
public:
void x() { }
};

class Bar { };

int main() {
std::cout << "Foo = " << std::is_member_function_pointer<decltype(&Foo::x)>::value << std::endl;
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;
return 0;
}


Compiler says:



is_member_function_pointer.cpp:17:69: error: no member named 'x' in 'Bar'; did you mean 'Foo::x'?
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;


So, what is the std::is_member_function_pointer for, when I can not use it in an if constexpr? If I just use this->_t->x() the compiler will fail, too, for sure.










share|improve this question























  • you don't check if the type is a function pointer, you try to see a function pointer which did not exist

    – Klaus
    18 hours ago











  • Thanks for your comment! But how can I check that?

    – jagemue
    18 hours ago











  • stackoverflow.com/questions/257288/…

    – Klaus
    18 hours ago











  • Possible duplicate of Is it possible to write a template to check for a function's existence?

    – Klaus
    18 hours ago
















9















What I am looking for: I have a templated class and want to call a function if the class has the wanted function, something like:



template<class T> do_something() {
if constexpr (std::is_member_function_pointer<decltype(&T::x)>::value) {
this->_t->x(); // _t is type of T*
}
}


What happens: The compiler does not compile if T does not bring the function. Small example:



#include <type_traits>
#include <iostream>

class Foo {
public:
void x() { }
};

class Bar { };

int main() {
std::cout << "Foo = " << std::is_member_function_pointer<decltype(&Foo::x)>::value << std::endl;
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;
return 0;
}


Compiler says:



is_member_function_pointer.cpp:17:69: error: no member named 'x' in 'Bar'; did you mean 'Foo::x'?
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;


So, what is the std::is_member_function_pointer for, when I can not use it in an if constexpr? If I just use this->_t->x() the compiler will fail, too, for sure.










share|improve this question























  • you don't check if the type is a function pointer, you try to see a function pointer which did not exist

    – Klaus
    18 hours ago











  • Thanks for your comment! But how can I check that?

    – jagemue
    18 hours ago











  • stackoverflow.com/questions/257288/…

    – Klaus
    18 hours ago











  • Possible duplicate of Is it possible to write a template to check for a function's existence?

    – Klaus
    18 hours ago














9












9








9


2






What I am looking for: I have a templated class and want to call a function if the class has the wanted function, something like:



template<class T> do_something() {
if constexpr (std::is_member_function_pointer<decltype(&T::x)>::value) {
this->_t->x(); // _t is type of T*
}
}


What happens: The compiler does not compile if T does not bring the function. Small example:



#include <type_traits>
#include <iostream>

class Foo {
public:
void x() { }
};

class Bar { };

int main() {
std::cout << "Foo = " << std::is_member_function_pointer<decltype(&Foo::x)>::value << std::endl;
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;
return 0;
}


Compiler says:



is_member_function_pointer.cpp:17:69: error: no member named 'x' in 'Bar'; did you mean 'Foo::x'?
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;


So, what is the std::is_member_function_pointer for, when I can not use it in an if constexpr? If I just use this->_t->x() the compiler will fail, too, for sure.










share|improve this question














What I am looking for: I have a templated class and want to call a function if the class has the wanted function, something like:



template<class T> do_something() {
if constexpr (std::is_member_function_pointer<decltype(&T::x)>::value) {
this->_t->x(); // _t is type of T*
}
}


What happens: The compiler does not compile if T does not bring the function. Small example:



#include <type_traits>
#include <iostream>

class Foo {
public:
void x() { }
};

class Bar { };

int main() {
std::cout << "Foo = " << std::is_member_function_pointer<decltype(&Foo::x)>::value << std::endl;
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;
return 0;
}


Compiler says:



is_member_function_pointer.cpp:17:69: error: no member named 'x' in 'Bar'; did you mean 'Foo::x'?
std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;


So, what is the std::is_member_function_pointer for, when I can not use it in an if constexpr? If I just use this->_t->x() the compiler will fail, too, for sure.







c++ typetraits if-constexpr






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 18 hours ago









jagemuejagemue

15919




15919













  • you don't check if the type is a function pointer, you try to see a function pointer which did not exist

    – Klaus
    18 hours ago











  • Thanks for your comment! But how can I check that?

    – jagemue
    18 hours ago











  • stackoverflow.com/questions/257288/…

    – Klaus
    18 hours ago











  • Possible duplicate of Is it possible to write a template to check for a function's existence?

    – Klaus
    18 hours ago



















  • you don't check if the type is a function pointer, you try to see a function pointer which did not exist

    – Klaus
    18 hours ago











  • Thanks for your comment! But how can I check that?

    – jagemue
    18 hours ago











  • stackoverflow.com/questions/257288/…

    – Klaus
    18 hours ago











  • Possible duplicate of Is it possible to write a template to check for a function's existence?

    – Klaus
    18 hours ago

















you don't check if the type is a function pointer, you try to see a function pointer which did not exist

– Klaus
18 hours ago





you don't check if the type is a function pointer, you try to see a function pointer which did not exist

– Klaus
18 hours ago













Thanks for your comment! But how can I check that?

– jagemue
18 hours ago





Thanks for your comment! But how can I check that?

– jagemue
18 hours ago













stackoverflow.com/questions/257288/…

– Klaus
18 hours ago





stackoverflow.com/questions/257288/…

– Klaus
18 hours ago













Possible duplicate of Is it possible to write a template to check for a function's existence?

– Klaus
18 hours ago





Possible duplicate of Is it possible to write a template to check for a function's existence?

– Klaus
18 hours ago












1 Answer
1






active

oldest

votes


















15














is_member_function_pointer doesn't detect the existence of an entity T::x, it assumes it does and returns whether or not it is a member function pointer.



If you want to detect whether it exists or not, you can use the detection idiom. Example:



#include <experimental/type_traits>

template<class T>
using has_x = decltype(&T::x);

template<class T> void do_something(T t) {
if constexpr (std::experimental::is_detected<has_x, T>::value) {
t.x();
}
}

struct Foo {
void x() { }
};

struct Bar { };

int main() {
do_something(Foo{});
do_something(Bar{});
}


live example on godbolt.org





I have written an article on the general problem of checking the validity of an expression in different C++ Standard versions:



"checking expression validity in-place with C++17"






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55161832%2fstdis-member-function-pointer-does-not-compile-if-false%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    15














    is_member_function_pointer doesn't detect the existence of an entity T::x, it assumes it does and returns whether or not it is a member function pointer.



    If you want to detect whether it exists or not, you can use the detection idiom. Example:



    #include <experimental/type_traits>

    template<class T>
    using has_x = decltype(&T::x);

    template<class T> void do_something(T t) {
    if constexpr (std::experimental::is_detected<has_x, T>::value) {
    t.x();
    }
    }

    struct Foo {
    void x() { }
    };

    struct Bar { };

    int main() {
    do_something(Foo{});
    do_something(Bar{});
    }


    live example on godbolt.org





    I have written an article on the general problem of checking the validity of an expression in different C++ Standard versions:



    "checking expression validity in-place with C++17"






    share|improve this answer




























      15














      is_member_function_pointer doesn't detect the existence of an entity T::x, it assumes it does and returns whether or not it is a member function pointer.



      If you want to detect whether it exists or not, you can use the detection idiom. Example:



      #include <experimental/type_traits>

      template<class T>
      using has_x = decltype(&T::x);

      template<class T> void do_something(T t) {
      if constexpr (std::experimental::is_detected<has_x, T>::value) {
      t.x();
      }
      }

      struct Foo {
      void x() { }
      };

      struct Bar { };

      int main() {
      do_something(Foo{});
      do_something(Bar{});
      }


      live example on godbolt.org





      I have written an article on the general problem of checking the validity of an expression in different C++ Standard versions:



      "checking expression validity in-place with C++17"






      share|improve this answer


























        15












        15








        15







        is_member_function_pointer doesn't detect the existence of an entity T::x, it assumes it does and returns whether or not it is a member function pointer.



        If you want to detect whether it exists or not, you can use the detection idiom. Example:



        #include <experimental/type_traits>

        template<class T>
        using has_x = decltype(&T::x);

        template<class T> void do_something(T t) {
        if constexpr (std::experimental::is_detected<has_x, T>::value) {
        t.x();
        }
        }

        struct Foo {
        void x() { }
        };

        struct Bar { };

        int main() {
        do_something(Foo{});
        do_something(Bar{});
        }


        live example on godbolt.org





        I have written an article on the general problem of checking the validity of an expression in different C++ Standard versions:



        "checking expression validity in-place with C++17"






        share|improve this answer













        is_member_function_pointer doesn't detect the existence of an entity T::x, it assumes it does and returns whether or not it is a member function pointer.



        If you want to detect whether it exists or not, you can use the detection idiom. Example:



        #include <experimental/type_traits>

        template<class T>
        using has_x = decltype(&T::x);

        template<class T> void do_something(T t) {
        if constexpr (std::experimental::is_detected<has_x, T>::value) {
        t.x();
        }
        }

        struct Foo {
        void x() { }
        };

        struct Bar { };

        int main() {
        do_something(Foo{});
        do_something(Bar{});
        }


        live example on godbolt.org





        I have written an article on the general problem of checking the validity of an expression in different C++ Standard versions:



        "checking expression validity in-place with C++17"







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 18 hours ago









        Vittorio RomeoVittorio Romeo

        58.9k17161304




        58.9k17161304
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55161832%2fstdis-member-function-pointer-does-not-compile-if-false%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            Origin of the phrase “under your belt”?