How to make a function template a parameter to a test?









up vote
0
down vote

favorite












I want to unit test equivalent templated member function of a class template. (As a background, I want to offer the users of the library "classical" function notation with .bar() and a tacit notation with |, &, etc. But I do not want to duplicate the complete test code.)



#include <utility> 

template <typename T>
struct foo
(U&& u)&&
return bar(std::forward<U>(u));


template <typename U>
auto bar(U&& u) const&
// whatever happens here.
return foo<T>();


template <typename U>
auto operator;

int main()
using void_t = void();
using op_t = foo<void>(foo<void>::*)(void_t)&&;

op_t ops = static_cast<op_t>(&foo<void>::bar<void_t>),
static_cast<op_t>(&foo<void>::operator;

for (const auto& op : ops)
auto sut = (foo<void>.*op)(());
// test the behaviour of sut




clang e.g., reports me that "the address of overloaded function 'bar' cannot be static_cast to type 'op_t'"



Or am I on the wrong track and this is not possible?
(I tried clang 6 and gcc 7)










share|improve this question





















  • What would &foo<void>::bar<void_t> be in the first place, given that bar is not a static member?
    – Henning Koehler
    2 days ago











  • @HenningKoehler A pointer to member.
    – melpomene
    2 days ago










  • But for a non-static member to exist, you need to have an instance first ...
    – Henning Koehler
    2 days ago






  • 1




    I can get this code to compile by changing op_t to using op_t = foo<void>(foo<void>::*)(void_t &&) &&; and sut to auto sut = (foo<void>.*op)(*());. Alternatively, instead of changing sut, you can also change void_t to using void_t = void (*)();.
    – melpomene
    2 days ago







  • 2




    Off Topic: starting from C++17, std::void_t is part of the standard (with a completely different meaning). To avoid clashes, I suggest to give another name to your void_t
    – max66
    2 days ago














up vote
0
down vote

favorite












I want to unit test equivalent templated member function of a class template. (As a background, I want to offer the users of the library "classical" function notation with .bar() and a tacit notation with |, &, etc. But I do not want to duplicate the complete test code.)



#include <utility> 

template <typename T>
struct foo
(U&& u)&&
return bar(std::forward<U>(u));


template <typename U>
auto bar(U&& u) const&
// whatever happens here.
return foo<T>();


template <typename U>
auto operator;

int main()
using void_t = void();
using op_t = foo<void>(foo<void>::*)(void_t)&&;

op_t ops = static_cast<op_t>(&foo<void>::bar<void_t>),
static_cast<op_t>(&foo<void>::operator;

for (const auto& op : ops)
auto sut = (foo<void>.*op)(());
// test the behaviour of sut




clang e.g., reports me that "the address of overloaded function 'bar' cannot be static_cast to type 'op_t'"



Or am I on the wrong track and this is not possible?
(I tried clang 6 and gcc 7)










share|improve this question





















  • What would &foo<void>::bar<void_t> be in the first place, given that bar is not a static member?
    – Henning Koehler
    2 days ago











  • @HenningKoehler A pointer to member.
    – melpomene
    2 days ago










  • But for a non-static member to exist, you need to have an instance first ...
    – Henning Koehler
    2 days ago






  • 1




    I can get this code to compile by changing op_t to using op_t = foo<void>(foo<void>::*)(void_t &&) &&; and sut to auto sut = (foo<void>.*op)(*());. Alternatively, instead of changing sut, you can also change void_t to using void_t = void (*)();.
    – melpomene
    2 days ago







  • 2




    Off Topic: starting from C++17, std::void_t is part of the standard (with a completely different meaning). To avoid clashes, I suggest to give another name to your void_t
    – max66
    2 days ago












up vote
0
down vote

favorite









up vote
0
down vote

favorite











I want to unit test equivalent templated member function of a class template. (As a background, I want to offer the users of the library "classical" function notation with .bar() and a tacit notation with |, &, etc. But I do not want to duplicate the complete test code.)



#include <utility> 

template <typename T>
struct foo
(U&& u)&&
return bar(std::forward<U>(u));


template <typename U>
auto bar(U&& u) const&
// whatever happens here.
return foo<T>();


template <typename U>
auto operator;

int main()
using void_t = void();
using op_t = foo<void>(foo<void>::*)(void_t)&&;

op_t ops = static_cast<op_t>(&foo<void>::bar<void_t>),
static_cast<op_t>(&foo<void>::operator;

for (const auto& op : ops)
auto sut = (foo<void>.*op)(());
// test the behaviour of sut




clang e.g., reports me that "the address of overloaded function 'bar' cannot be static_cast to type 'op_t'"



Or am I on the wrong track and this is not possible?
(I tried clang 6 and gcc 7)










share|improve this question













I want to unit test equivalent templated member function of a class template. (As a background, I want to offer the users of the library "classical" function notation with .bar() and a tacit notation with |, &, etc. But I do not want to duplicate the complete test code.)



#include <utility> 

template <typename T>
struct foo
(U&& u)&&
return bar(std::forward<U>(u));


template <typename U>
auto bar(U&& u) const&
// whatever happens here.
return foo<T>();


template <typename U>
auto operator;

int main()
using void_t = void();
using op_t = foo<void>(foo<void>::*)(void_t)&&;

op_t ops = static_cast<op_t>(&foo<void>::bar<void_t>),
static_cast<op_t>(&foo<void>::operator;

for (const auto& op : ops)
auto sut = (foo<void>.*op)(());
// test the behaviour of sut




clang e.g., reports me that "the address of overloaded function 'bar' cannot be static_cast to type 'op_t'"



Or am I on the wrong track and this is not possible?
(I tried clang 6 and gcc 7)







c++ templates






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 2 days ago









Felix Petriconi

370210




370210











  • What would &foo<void>::bar<void_t> be in the first place, given that bar is not a static member?
    – Henning Koehler
    2 days ago











  • @HenningKoehler A pointer to member.
    – melpomene
    2 days ago










  • But for a non-static member to exist, you need to have an instance first ...
    – Henning Koehler
    2 days ago






  • 1




    I can get this code to compile by changing op_t to using op_t = foo<void>(foo<void>::*)(void_t &&) &&; and sut to auto sut = (foo<void>.*op)(*());. Alternatively, instead of changing sut, you can also change void_t to using void_t = void (*)();.
    – melpomene
    2 days ago







  • 2




    Off Topic: starting from C++17, std::void_t is part of the standard (with a completely different meaning). To avoid clashes, I suggest to give another name to your void_t
    – max66
    2 days ago
















  • What would &foo<void>::bar<void_t> be in the first place, given that bar is not a static member?
    – Henning Koehler
    2 days ago











  • @HenningKoehler A pointer to member.
    – melpomene
    2 days ago










  • But for a non-static member to exist, you need to have an instance first ...
    – Henning Koehler
    2 days ago






  • 1




    I can get this code to compile by changing op_t to using op_t = foo<void>(foo<void>::*)(void_t &&) &&; and sut to auto sut = (foo<void>.*op)(*());. Alternatively, instead of changing sut, you can also change void_t to using void_t = void (*)();.
    – melpomene
    2 days ago







  • 2




    Off Topic: starting from C++17, std::void_t is part of the standard (with a completely different meaning). To avoid clashes, I suggest to give another name to your void_t
    – max66
    2 days ago















What would &foo<void>::bar<void_t> be in the first place, given that bar is not a static member?
– Henning Koehler
2 days ago





What would &foo<void>::bar<void_t> be in the first place, given that bar is not a static member?
– Henning Koehler
2 days ago













@HenningKoehler A pointer to member.
– melpomene
2 days ago




@HenningKoehler A pointer to member.
– melpomene
2 days ago












But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
2 days ago




But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
2 days ago




1




1




I can get this code to compile by changing op_t to using op_t = foo<void>(foo<void>::*)(void_t &&) &&; and sut to auto sut = (foo<void>.*op)(*());. Alternatively, instead of changing sut, you can also change void_t to using void_t = void (*)();.
– melpomene
2 days ago





I can get this code to compile by changing op_t to using op_t = foo<void>(foo<void>::*)(void_t &&) &&; and sut to auto sut = (foo<void>.*op)(*());. Alternatively, instead of changing sut, you can also change void_t to using void_t = void (*)();.
– melpomene
2 days ago





2




2




Off Topic: starting from C++17, std::void_t is part of the standard (with a completely different meaning). To avoid clashes, I suggest to give another name to your void_t
– max66
2 days ago




Off Topic: starting from C++17, std::void_t is part of the standard (with a completely different meaning). To avoid clashes, I suggest to give another name to your void_t
– max66
2 days ago












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










I can get the code to compile by changing op_t to



using op_t = foo<void>(foo<void>::*)(void_t &&) &&;
// ^^


and sut to



auto sut = (foo<void>.*op)(*());
// ^


(() can be converted to a function pointer, but *op takes a reference to a function, so we have to dereference the pointer).



Alternatively, instead of changing sut, you can also change void_t to



using void_t = void (*)();
// ^^^


Now void_t is already a function pointer, so you don't have to dereference.






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',
    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%2f53238301%2fhow-to-make-a-function-template-a-parameter-to-a-test%23new-answer', 'question_page');

    );

    Post as a guest






























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    I can get the code to compile by changing op_t to



    using op_t = foo<void>(foo<void>::*)(void_t &&) &&;
    // ^^


    and sut to



    auto sut = (foo<void>.*op)(*());
    // ^


    (() can be converted to a function pointer, but *op takes a reference to a function, so we have to dereference the pointer).



    Alternatively, instead of changing sut, you can also change void_t to



    using void_t = void (*)();
    // ^^^


    Now void_t is already a function pointer, so you don't have to dereference.






    share|improve this answer
























      up vote
      1
      down vote



      accepted










      I can get the code to compile by changing op_t to



      using op_t = foo<void>(foo<void>::*)(void_t &&) &&;
      // ^^


      and sut to



      auto sut = (foo<void>.*op)(*());
      // ^


      (() can be converted to a function pointer, but *op takes a reference to a function, so we have to dereference the pointer).



      Alternatively, instead of changing sut, you can also change void_t to



      using void_t = void (*)();
      // ^^^


      Now void_t is already a function pointer, so you don't have to dereference.






      share|improve this answer






















        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        I can get the code to compile by changing op_t to



        using op_t = foo<void>(foo<void>::*)(void_t &&) &&;
        // ^^


        and sut to



        auto sut = (foo<void>.*op)(*());
        // ^


        (() can be converted to a function pointer, but *op takes a reference to a function, so we have to dereference the pointer).



        Alternatively, instead of changing sut, you can also change void_t to



        using void_t = void (*)();
        // ^^^


        Now void_t is already a function pointer, so you don't have to dereference.






        share|improve this answer












        I can get the code to compile by changing op_t to



        using op_t = foo<void>(foo<void>::*)(void_t &&) &&;
        // ^^


        and sut to



        auto sut = (foo<void>.*op)(*());
        // ^


        (() can be converted to a function pointer, but *op takes a reference to a function, so we have to dereference the pointer).



        Alternatively, instead of changing sut, you can also change void_t to



        using void_t = void (*)();
        // ^^^


        Now void_t is already a function pointer, so you don't have to dereference.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 2 days ago









        melpomene

        55.6k54387




        55.6k54387



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53238301%2fhow-to-make-a-function-template-a-parameter-to-a-test%23new-answer', 'question_page');

            );

            Post as a guest














































































            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            政党