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
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 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
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 yourvoid_t
– max66
2 days ago
|
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 2 days ago
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
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 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
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 yourvoid_t
– max66
2 days ago
|
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
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 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
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 yourvoid_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
|
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 2 days ago
melpomene
55.6k54387
55.6k54387
add a comment |
add a comment |
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
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
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
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
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
What would
&foo<void>::bar<void_t>
be in the first place, given thatbar
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
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
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 yourvoid_t
– max66
2 days ago