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)
c++ templates
|
show 2 more comments
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)
c++ templates
What would&foo<void>::bar<void_t>
be in the first place, given thatbar
is not a static member?
– Henning Koehler
Nov 10 at 11:15
@HenningKoehler A pointer to member.
– melpomene
Nov 10 at 11:23
But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
Nov 10 at 11:25
1
I can get this code to compile by changingop_t
tousing op_t = foo<void>(foo<void>::*)(void_t &&) &&;
andsut
toauto sut = (foo<void>.*op)(*());
. Alternatively, instead of changingsut
, you can also changevoid_t
tousing void_t = void (*)();
.
– melpomene
Nov 10 at 11:59
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 yourvoid_t
– max66
Nov 10 at 13:14
|
show 2 more comments
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)
c++ templates
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
c++ templates
asked Nov 10 at 11:04
Felix Petriconi
370210
370210
What would&foo<void>::bar<void_t>
be in the first place, given thatbar
is not a static member?
– Henning Koehler
Nov 10 at 11:15
@HenningKoehler A pointer to member.
– melpomene
Nov 10 at 11:23
But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
Nov 10 at 11:25
1
I can get this code to compile by changingop_t
tousing op_t = foo<void>(foo<void>::*)(void_t &&) &&;
andsut
toauto sut = (foo<void>.*op)(*());
. Alternatively, instead of changingsut
, you can also changevoid_t
tousing void_t = void (*)();
.
– melpomene
Nov 10 at 11:59
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 yourvoid_t
– max66
Nov 10 at 13:14
|
show 2 more comments
What would&foo<void>::bar<void_t>
be in the first place, given thatbar
is not a static member?
– Henning Koehler
Nov 10 at 11:15
@HenningKoehler A pointer to member.
– melpomene
Nov 10 at 11:23
But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
Nov 10 at 11:25
1
I can get this code to compile by changingop_t
tousing op_t = foo<void>(foo<void>::*)(void_t &&) &&;
andsut
toauto sut = (foo<void>.*op)(*());
. Alternatively, instead of changingsut
, you can also changevoid_t
tousing void_t = void (*)();
.
– melpomene
Nov 10 at 11:59
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 yourvoid_t
– max66
Nov 10 at 13:14
What would
&foo<void>::bar<void_t>
be in the first place, given that bar
is not a static member?– Henning Koehler
Nov 10 at 11:15
What would
&foo<void>::bar<void_t>
be in the first place, given that bar
is not a static member?– Henning Koehler
Nov 10 at 11:15
@HenningKoehler A pointer to member.
– melpomene
Nov 10 at 11:23
@HenningKoehler A pointer to member.
– melpomene
Nov 10 at 11:23
But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
Nov 10 at 11:25
But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
Nov 10 at 11:25
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
Nov 10 at 11:59
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
Nov 10 at 11:59
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
Nov 10 at 13:14
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
Nov 10 at 13:14
|
show 2 more comments
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.
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 10 at 12:33
melpomene
57.4k54489
57.4k54489
add a comment |
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
What would
&foo<void>::bar<void_t>
be in the first place, given thatbar
is not a static member?– Henning Koehler
Nov 10 at 11:15
@HenningKoehler A pointer to member.
– melpomene
Nov 10 at 11:23
But for a non-static member to exist, you need to have an instance first ...
– Henning Koehler
Nov 10 at 11:25
1
I can get this code to compile by changing
op_t
tousing op_t = foo<void>(foo<void>::*)(void_t &&) &&;
andsut
toauto sut = (foo<void>.*op)(*());
. Alternatively, instead of changingsut
, you can also changevoid_t
tousing void_t = void (*)();
.– melpomene
Nov 10 at 11:59
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 yourvoid_t
– max66
Nov 10 at 13:14