How to get the value type from an output iterator?
Let's say that I have a C container (e.g., MyContainer
) with contained objects stored as void*
pointers. The only way to iterate through the elements of this container is via two interface functions:
getFirstElem(MyContainer const&, void*)
: Outputs the first element of the container.
getNextElem(MyContainer const&, void*)
: Outputs the next element of the container.
I want to code a generic function that iterates through the elements of this C container via the interface functions mentioned above and copy their values into a C++ container (e.g. std::vector
).
What I've done so far:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename std::iterator_traits<OutputIterator>::value_type elem;
if(getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while(getNextElem(cont, &elem))
}
}
The above example works OK with normal iterators. However, it fails to compile with output iterators (e.g., copy_container(cont, std::back_inserter(myvector));
).
The reason is that std::iterator_traits::value_type
results in void
in cases where the argument type is an output iterator.
Is there a way to make this generic function work for output iterators as well?
I know that in C++11 it could be done by using decltype
(e.g., decltype(*first)
), but I'm particularly interested in pre-C++11 solutions since I use an old C++ compiler (gcc v4.4.7).
c++ stl iterator c++03
add a comment |
Let's say that I have a C container (e.g., MyContainer
) with contained objects stored as void*
pointers. The only way to iterate through the elements of this container is via two interface functions:
getFirstElem(MyContainer const&, void*)
: Outputs the first element of the container.
getNextElem(MyContainer const&, void*)
: Outputs the next element of the container.
I want to code a generic function that iterates through the elements of this C container via the interface functions mentioned above and copy their values into a C++ container (e.g. std::vector
).
What I've done so far:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename std::iterator_traits<OutputIterator>::value_type elem;
if(getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while(getNextElem(cont, &elem))
}
}
The above example works OK with normal iterators. However, it fails to compile with output iterators (e.g., copy_container(cont, std::back_inserter(myvector));
).
The reason is that std::iterator_traits::value_type
results in void
in cases where the argument type is an output iterator.
Is there a way to make this generic function work for output iterators as well?
I know that in C++11 it could be done by using decltype
(e.g., decltype(*first)
), but I'm particularly interested in pre-C++11 solutions since I use an old C++ compiler (gcc v4.4.7).
c++ stl iterator c++03
1
Even in C++11,decltype(*first)
is not the solution cause of proxy (as it is the case forstd::back_inserter
).
– Jarod42
Aug 4 '14 at 13:04
add a comment |
Let's say that I have a C container (e.g., MyContainer
) with contained objects stored as void*
pointers. The only way to iterate through the elements of this container is via two interface functions:
getFirstElem(MyContainer const&, void*)
: Outputs the first element of the container.
getNextElem(MyContainer const&, void*)
: Outputs the next element of the container.
I want to code a generic function that iterates through the elements of this C container via the interface functions mentioned above and copy their values into a C++ container (e.g. std::vector
).
What I've done so far:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename std::iterator_traits<OutputIterator>::value_type elem;
if(getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while(getNextElem(cont, &elem))
}
}
The above example works OK with normal iterators. However, it fails to compile with output iterators (e.g., copy_container(cont, std::back_inserter(myvector));
).
The reason is that std::iterator_traits::value_type
results in void
in cases where the argument type is an output iterator.
Is there a way to make this generic function work for output iterators as well?
I know that in C++11 it could be done by using decltype
(e.g., decltype(*first)
), but I'm particularly interested in pre-C++11 solutions since I use an old C++ compiler (gcc v4.4.7).
c++ stl iterator c++03
Let's say that I have a C container (e.g., MyContainer
) with contained objects stored as void*
pointers. The only way to iterate through the elements of this container is via two interface functions:
getFirstElem(MyContainer const&, void*)
: Outputs the first element of the container.
getNextElem(MyContainer const&, void*)
: Outputs the next element of the container.
I want to code a generic function that iterates through the elements of this C container via the interface functions mentioned above and copy their values into a C++ container (e.g. std::vector
).
What I've done so far:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename std::iterator_traits<OutputIterator>::value_type elem;
if(getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while(getNextElem(cont, &elem))
}
}
The above example works OK with normal iterators. However, it fails to compile with output iterators (e.g., copy_container(cont, std::back_inserter(myvector));
).
The reason is that std::iterator_traits::value_type
results in void
in cases where the argument type is an output iterator.
Is there a way to make this generic function work for output iterators as well?
I know that in C++11 it could be done by using decltype
(e.g., decltype(*first)
), but I'm particularly interested in pre-C++11 solutions since I use an old C++ compiler (gcc v4.4.7).
c++ stl iterator c++03
c++ stl iterator c++03
edited Aug 4 '14 at 13:11
michaelb958
3,79972433
3,79972433
asked Aug 4 '14 at 12:07
101010101010
31.4k762123
31.4k762123
1
Even in C++11,decltype(*first)
is not the solution cause of proxy (as it is the case forstd::back_inserter
).
– Jarod42
Aug 4 '14 at 13:04
add a comment |
1
Even in C++11,decltype(*first)
is not the solution cause of proxy (as it is the case forstd::back_inserter
).
– Jarod42
Aug 4 '14 at 13:04
1
1
Even in C++11,
decltype(*first)
is not the solution cause of proxy (as it is the case for std::back_inserter
).– Jarod42
Aug 4 '14 at 13:04
Even in C++11,
decltype(*first)
is not the solution cause of proxy (as it is the case for std::back_inserter
).– Jarod42
Aug 4 '14 at 13:04
add a comment |
3 Answers
3
active
oldest
votes
As correctly observed, the value_type
of an output iterator is void
. So there not much to do apart from replacing this :
typename std::iterator_traits<OutputIterator>::value_type elem;
with this
decltype(*first) elem;
(even though the Standard doesn't guarantee it'll work - a proxy might be returned by dereferencing an output iterator).
As you said no C++11 solution so a redesign might be needed. Here are some options:
1. Pass the container
Instead of an iterator to the first element, you could pass a reference to the container. It seems like all you want is a push_back
.
template<template<typename,typename> class stlContainer>
void copy_container(
MyMontainer const &cont, OutputIterator first)
{
// insertion in stlContainer
then all you need is a layer of traits to dispatch to the right implementation of insertion per container
2. Pass an extra template parameter
The value type could be an extra template parameter.
template<typename value_type, typename OutputIterator>
void copy_container(MyMontainer const &cont, OutputIterator first)
{
value_type elem;
...
1
decltype(*first)
is still thestd::back_inserter
for me (gcc 4.8.1). And it isstd::back_inserter::operator =(const value_type&)
which is implemented for proxy.
– Jarod42
Aug 4 '14 at 13:01
@Jarod42 What's the dispute here? Inback_insert_iterator
andraw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?
– Nikos Athanasiou
Aug 4 '14 at 13:06
1
It was just a clarification/example thatdecltype(*first)
doesn't work for all cases.
– Jarod42
Aug 4 '14 at 13:10
add a comment |
You may use typetraits and specialization
template <typename IT>
struct it_value_type
{
typedef typename std::iterator_traits<IT>::value_type elem;
};
template <typename Container>
struct it_value_type<std::back_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
template <typename Container>
struct it_value_type<std::front_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
And then you code becomes:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename it_value_type<OutputIterator>::elem elem;
if (getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while (getNextElem(cont, &elem));
}
}
How this solution works? When you callcopy_container
with aback_inserter
how the compiler will decide whichit_value_type
struct to use, since bothtemplate <typename IT> struct it_value_type
andtemplate <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.
– Dejan
Nov 13 '18 at 11:18
@Dejan:std::back_inserter
is more specialized thanIT
.
– Jarod42
Nov 13 '18 at 11:48
add a comment |
There are different ways to solve this, I did it like this:
template <class T>
std::enable_if_t<!std::is_same_v<typename T::container_type::value_type, void>, size_t> read(T first, size_t count)
{
typedef typename T::container_type::value_type value_type;
I have another one for the usual iterator.
add a comment |
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
});
}
});
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%2f25118328%2fhow-to-get-the-value-type-from-an-output-iterator%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
As correctly observed, the value_type
of an output iterator is void
. So there not much to do apart from replacing this :
typename std::iterator_traits<OutputIterator>::value_type elem;
with this
decltype(*first) elem;
(even though the Standard doesn't guarantee it'll work - a proxy might be returned by dereferencing an output iterator).
As you said no C++11 solution so a redesign might be needed. Here are some options:
1. Pass the container
Instead of an iterator to the first element, you could pass a reference to the container. It seems like all you want is a push_back
.
template<template<typename,typename> class stlContainer>
void copy_container(
MyMontainer const &cont, OutputIterator first)
{
// insertion in stlContainer
then all you need is a layer of traits to dispatch to the right implementation of insertion per container
2. Pass an extra template parameter
The value type could be an extra template parameter.
template<typename value_type, typename OutputIterator>
void copy_container(MyMontainer const &cont, OutputIterator first)
{
value_type elem;
...
1
decltype(*first)
is still thestd::back_inserter
for me (gcc 4.8.1). And it isstd::back_inserter::operator =(const value_type&)
which is implemented for proxy.
– Jarod42
Aug 4 '14 at 13:01
@Jarod42 What's the dispute here? Inback_insert_iterator
andraw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?
– Nikos Athanasiou
Aug 4 '14 at 13:06
1
It was just a clarification/example thatdecltype(*first)
doesn't work for all cases.
– Jarod42
Aug 4 '14 at 13:10
add a comment |
As correctly observed, the value_type
of an output iterator is void
. So there not much to do apart from replacing this :
typename std::iterator_traits<OutputIterator>::value_type elem;
with this
decltype(*first) elem;
(even though the Standard doesn't guarantee it'll work - a proxy might be returned by dereferencing an output iterator).
As you said no C++11 solution so a redesign might be needed. Here are some options:
1. Pass the container
Instead of an iterator to the first element, you could pass a reference to the container. It seems like all you want is a push_back
.
template<template<typename,typename> class stlContainer>
void copy_container(
MyMontainer const &cont, OutputIterator first)
{
// insertion in stlContainer
then all you need is a layer of traits to dispatch to the right implementation of insertion per container
2. Pass an extra template parameter
The value type could be an extra template parameter.
template<typename value_type, typename OutputIterator>
void copy_container(MyMontainer const &cont, OutputIterator first)
{
value_type elem;
...
1
decltype(*first)
is still thestd::back_inserter
for me (gcc 4.8.1). And it isstd::back_inserter::operator =(const value_type&)
which is implemented for proxy.
– Jarod42
Aug 4 '14 at 13:01
@Jarod42 What's the dispute here? Inback_insert_iterator
andraw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?
– Nikos Athanasiou
Aug 4 '14 at 13:06
1
It was just a clarification/example thatdecltype(*first)
doesn't work for all cases.
– Jarod42
Aug 4 '14 at 13:10
add a comment |
As correctly observed, the value_type
of an output iterator is void
. So there not much to do apart from replacing this :
typename std::iterator_traits<OutputIterator>::value_type elem;
with this
decltype(*first) elem;
(even though the Standard doesn't guarantee it'll work - a proxy might be returned by dereferencing an output iterator).
As you said no C++11 solution so a redesign might be needed. Here are some options:
1. Pass the container
Instead of an iterator to the first element, you could pass a reference to the container. It seems like all you want is a push_back
.
template<template<typename,typename> class stlContainer>
void copy_container(
MyMontainer const &cont, OutputIterator first)
{
// insertion in stlContainer
then all you need is a layer of traits to dispatch to the right implementation of insertion per container
2. Pass an extra template parameter
The value type could be an extra template parameter.
template<typename value_type, typename OutputIterator>
void copy_container(MyMontainer const &cont, OutputIterator first)
{
value_type elem;
...
As correctly observed, the value_type
of an output iterator is void
. So there not much to do apart from replacing this :
typename std::iterator_traits<OutputIterator>::value_type elem;
with this
decltype(*first) elem;
(even though the Standard doesn't guarantee it'll work - a proxy might be returned by dereferencing an output iterator).
As you said no C++11 solution so a redesign might be needed. Here are some options:
1. Pass the container
Instead of an iterator to the first element, you could pass a reference to the container. It seems like all you want is a push_back
.
template<template<typename,typename> class stlContainer>
void copy_container(
MyMontainer const &cont, OutputIterator first)
{
// insertion in stlContainer
then all you need is a layer of traits to dispatch to the right implementation of insertion per container
2. Pass an extra template parameter
The value type could be an extra template parameter.
template<typename value_type, typename OutputIterator>
void copy_container(MyMontainer const &cont, OutputIterator first)
{
value_type elem;
...
edited Jul 10 '18 at 18:41
ネロク
10.5k32140
10.5k32140
answered Aug 4 '14 at 12:31
Nikos AthanasiouNikos Athanasiou
16.2k1055112
16.2k1055112
1
decltype(*first)
is still thestd::back_inserter
for me (gcc 4.8.1). And it isstd::back_inserter::operator =(const value_type&)
which is implemented for proxy.
– Jarod42
Aug 4 '14 at 13:01
@Jarod42 What's the dispute here? Inback_insert_iterator
andraw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?
– Nikos Athanasiou
Aug 4 '14 at 13:06
1
It was just a clarification/example thatdecltype(*first)
doesn't work for all cases.
– Jarod42
Aug 4 '14 at 13:10
add a comment |
1
decltype(*first)
is still thestd::back_inserter
for me (gcc 4.8.1). And it isstd::back_inserter::operator =(const value_type&)
which is implemented for proxy.
– Jarod42
Aug 4 '14 at 13:01
@Jarod42 What's the dispute here? Inback_insert_iterator
andraw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?
– Nikos Athanasiou
Aug 4 '14 at 13:06
1
It was just a clarification/example thatdecltype(*first)
doesn't work for all cases.
– Jarod42
Aug 4 '14 at 13:10
1
1
decltype(*first)
is still the std::back_inserter
for me (gcc 4.8.1). And it is std::back_inserter::operator =(const value_type&)
which is implemented for proxy.– Jarod42
Aug 4 '14 at 13:01
decltype(*first)
is still the std::back_inserter
for me (gcc 4.8.1). And it is std::back_inserter::operator =(const value_type&)
which is implemented for proxy.– Jarod42
Aug 4 '14 at 13:01
@Jarod42 What's the dispute here? In
back_insert_iterator
and raw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?– Nikos Athanasiou
Aug 4 '14 at 13:06
@Jarod42 What's the dispute here? In
back_insert_iterator
and raw_storage_iterator
, operator * returns a proxy object for use in “dereferenced assignment,” typically a reference to the iterator itself. Am I communicating sth different?– Nikos Athanasiou
Aug 4 '14 at 13:06
1
1
It was just a clarification/example that
decltype(*first)
doesn't work for all cases.– Jarod42
Aug 4 '14 at 13:10
It was just a clarification/example that
decltype(*first)
doesn't work for all cases.– Jarod42
Aug 4 '14 at 13:10
add a comment |
You may use typetraits and specialization
template <typename IT>
struct it_value_type
{
typedef typename std::iterator_traits<IT>::value_type elem;
};
template <typename Container>
struct it_value_type<std::back_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
template <typename Container>
struct it_value_type<std::front_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
And then you code becomes:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename it_value_type<OutputIterator>::elem elem;
if (getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while (getNextElem(cont, &elem));
}
}
How this solution works? When you callcopy_container
with aback_inserter
how the compiler will decide whichit_value_type
struct to use, since bothtemplate <typename IT> struct it_value_type
andtemplate <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.
– Dejan
Nov 13 '18 at 11:18
@Dejan:std::back_inserter
is more specialized thanIT
.
– Jarod42
Nov 13 '18 at 11:48
add a comment |
You may use typetraits and specialization
template <typename IT>
struct it_value_type
{
typedef typename std::iterator_traits<IT>::value_type elem;
};
template <typename Container>
struct it_value_type<std::back_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
template <typename Container>
struct it_value_type<std::front_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
And then you code becomes:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename it_value_type<OutputIterator>::elem elem;
if (getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while (getNextElem(cont, &elem));
}
}
How this solution works? When you callcopy_container
with aback_inserter
how the compiler will decide whichit_value_type
struct to use, since bothtemplate <typename IT> struct it_value_type
andtemplate <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.
– Dejan
Nov 13 '18 at 11:18
@Dejan:std::back_inserter
is more specialized thanIT
.
– Jarod42
Nov 13 '18 at 11:48
add a comment |
You may use typetraits and specialization
template <typename IT>
struct it_value_type
{
typedef typename std::iterator_traits<IT>::value_type elem;
};
template <typename Container>
struct it_value_type<std::back_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
template <typename Container>
struct it_value_type<std::front_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
And then you code becomes:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename it_value_type<OutputIterator>::elem elem;
if (getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while (getNextElem(cont, &elem));
}
}
You may use typetraits and specialization
template <typename IT>
struct it_value_type
{
typedef typename std::iterator_traits<IT>::value_type elem;
};
template <typename Container>
struct it_value_type<std::back_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
template <typename Container>
struct it_value_type<std::front_insert_iterator<Container>>
{
typedef typename Container::value_type elem;
};
And then you code becomes:
template<typename OutputIterator>
void
copy_container(MyContainer const &cont, OutputIterator first) {
typename it_value_type<OutputIterator>::elem elem;
if (getFirstElem(cont, &elem)) {
do {
*first = elem;
++first;
} while (getNextElem(cont, &elem));
}
}
edited Nov 13 '18 at 11:34
answered Aug 4 '14 at 12:56
Jarod42Jarod42
114k12101182
114k12101182
How this solution works? When you callcopy_container
with aback_inserter
how the compiler will decide whichit_value_type
struct to use, since bothtemplate <typename IT> struct it_value_type
andtemplate <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.
– Dejan
Nov 13 '18 at 11:18
@Dejan:std::back_inserter
is more specialized thanIT
.
– Jarod42
Nov 13 '18 at 11:48
add a comment |
How this solution works? When you callcopy_container
with aback_inserter
how the compiler will decide whichit_value_type
struct to use, since bothtemplate <typename IT> struct it_value_type
andtemplate <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.
– Dejan
Nov 13 '18 at 11:18
@Dejan:std::back_inserter
is more specialized thanIT
.
– Jarod42
Nov 13 '18 at 11:48
How this solution works? When you call
copy_container
with a back_inserter
how the compiler will decide which it_value_type
struct to use, since both template <typename IT> struct it_value_type
and template <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.– Dejan
Nov 13 '18 at 11:18
How this solution works? When you call
copy_container
with a back_inserter
how the compiler will decide which it_value_type
struct to use, since both template <typename IT> struct it_value_type
and template <typename Container> struct it_value_type<std::back_insert_iterator<Container>>
are possible.– Dejan
Nov 13 '18 at 11:18
@Dejan:
std::back_inserter
is more specialized than IT
.– Jarod42
Nov 13 '18 at 11:48
@Dejan:
std::back_inserter
is more specialized than IT
.– Jarod42
Nov 13 '18 at 11:48
add a comment |
There are different ways to solve this, I did it like this:
template <class T>
std::enable_if_t<!std::is_same_v<typename T::container_type::value_type, void>, size_t> read(T first, size_t count)
{
typedef typename T::container_type::value_type value_type;
I have another one for the usual iterator.
add a comment |
There are different ways to solve this, I did it like this:
template <class T>
std::enable_if_t<!std::is_same_v<typename T::container_type::value_type, void>, size_t> read(T first, size_t count)
{
typedef typename T::container_type::value_type value_type;
I have another one for the usual iterator.
add a comment |
There are different ways to solve this, I did it like this:
template <class T>
std::enable_if_t<!std::is_same_v<typename T::container_type::value_type, void>, size_t> read(T first, size_t count)
{
typedef typename T::container_type::value_type value_type;
I have another one for the usual iterator.
There are different ways to solve this, I did it like this:
template <class T>
std::enable_if_t<!std::is_same_v<typename T::container_type::value_type, void>, size_t> read(T first, size_t count)
{
typedef typename T::container_type::value_type value_type;
I have another one for the usual iterator.
answered Dec 1 '17 at 8:54
Ion TodirelIon Todirel
2,8001916
2,8001916
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.
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%2f25118328%2fhow-to-get-the-value-type-from-an-output-iterator%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
1
Even in C++11,
decltype(*first)
is not the solution cause of proxy (as it is the case forstd::back_inserter
).– Jarod42
Aug 4 '14 at 13:04