Design iterator adaptor to convert between unrelated objects
I have the following MWE:
#include <iostream>
#include <vector>
using namespace std;
class LegacyWidgetData
private:
double _a;
double _b;
public:
LegacyWidgetData()
: _a(0), _b(0)
LegacyWidgetData(const double &a, const double &b)
: _a(a), _b(b)
LegacyWidgetData(const LegacyWidgetData& w)
: _a(w.a()), _b(w.b())
inline double &a()
return _a;
inline double a() const
return _a;
inline double &b()
return _b;
inline double b() const
return _b;
;
template <std::size_t D>
class GenericWidgetData
private:
double data[D];
public:
GenericWidgetData(double a, double b)
data[0] = a;
data[1] = b;
GenericWidgetData(double a, double b, double c)
data[0] = a;
data[1] = b;
data[2] = c;
double get(int idx)
return data[idx];
void set(int idx, const double& v)
data[idx] = v;
;
template <typename Iterator>
void dummyFunction(Iterator begin, Iterator end)
for (auto it = begin; it != end; it++)
cout << "Before: " << it->a() << "," << it->b() << "t";
it->a() += 1;
it->b() -= 1;
cout << "After: " << it->a() << "," << it->b() << "n";
int main()
vector<LegacyWidgetData> c11, 2, 3, 4, 5, 6;
dummyFunction(c1.begin(), c1.end());
vector<GenericWidgetData<3>> c21, 2, 3, 4, 5, 6, 7, 8, 9;
// dummyFunction(c2.begin(), c2.end()); // Will not compile
return 0;
I have the following assumptions/restrictions:
- I cannot modify the implementation of
LegacyWidgetData
ordummyFunction
- I can add methods to
GenericWidgetData
, and add any iterator adaptors as may be needed.
What I'd like to have is some sort of a iterator adaptor that when applied to any kind of iterator of GenericWidgetData
gives me an iterator that acts like an iterator of LegacyWidgetData
, without any caching/creation of intermediate object involved. Big props if this can be done in compile-time using template meta programming!
templates iterator c++14 template-meta-programming
add a comment |
I have the following MWE:
#include <iostream>
#include <vector>
using namespace std;
class LegacyWidgetData
private:
double _a;
double _b;
public:
LegacyWidgetData()
: _a(0), _b(0)
LegacyWidgetData(const double &a, const double &b)
: _a(a), _b(b)
LegacyWidgetData(const LegacyWidgetData& w)
: _a(w.a()), _b(w.b())
inline double &a()
return _a;
inline double a() const
return _a;
inline double &b()
return _b;
inline double b() const
return _b;
;
template <std::size_t D>
class GenericWidgetData
private:
double data[D];
public:
GenericWidgetData(double a, double b)
data[0] = a;
data[1] = b;
GenericWidgetData(double a, double b, double c)
data[0] = a;
data[1] = b;
data[2] = c;
double get(int idx)
return data[idx];
void set(int idx, const double& v)
data[idx] = v;
;
template <typename Iterator>
void dummyFunction(Iterator begin, Iterator end)
for (auto it = begin; it != end; it++)
cout << "Before: " << it->a() << "," << it->b() << "t";
it->a() += 1;
it->b() -= 1;
cout << "After: " << it->a() << "," << it->b() << "n";
int main()
vector<LegacyWidgetData> c11, 2, 3, 4, 5, 6;
dummyFunction(c1.begin(), c1.end());
vector<GenericWidgetData<3>> c21, 2, 3, 4, 5, 6, 7, 8, 9;
// dummyFunction(c2.begin(), c2.end()); // Will not compile
return 0;
I have the following assumptions/restrictions:
- I cannot modify the implementation of
LegacyWidgetData
ordummyFunction
- I can add methods to
GenericWidgetData
, and add any iterator adaptors as may be needed.
What I'd like to have is some sort of a iterator adaptor that when applied to any kind of iterator of GenericWidgetData
gives me an iterator that acts like an iterator of LegacyWidgetData
, without any caching/creation of intermediate object involved. Big props if this can be done in compile-time using template meta programming!
templates iterator c++14 template-meta-programming
Why would you expect it to compile asdummyFunction
use members functionsa
andb
which does not exists inGenericWidgetData
. It might help to read compiler error message!
– Phil1970
Nov 14 '18 at 1:42
@Phil1970 It might help if you read the question in its entirety
– TCSGrad
Nov 14 '18 at 1:55
Read your question again and tell me where is the question. The purpose of the site is not to write code for other peoples or do their homework.
– Phil1970
Nov 14 '18 at 2:40
add a comment |
I have the following MWE:
#include <iostream>
#include <vector>
using namespace std;
class LegacyWidgetData
private:
double _a;
double _b;
public:
LegacyWidgetData()
: _a(0), _b(0)
LegacyWidgetData(const double &a, const double &b)
: _a(a), _b(b)
LegacyWidgetData(const LegacyWidgetData& w)
: _a(w.a()), _b(w.b())
inline double &a()
return _a;
inline double a() const
return _a;
inline double &b()
return _b;
inline double b() const
return _b;
;
template <std::size_t D>
class GenericWidgetData
private:
double data[D];
public:
GenericWidgetData(double a, double b)
data[0] = a;
data[1] = b;
GenericWidgetData(double a, double b, double c)
data[0] = a;
data[1] = b;
data[2] = c;
double get(int idx)
return data[idx];
void set(int idx, const double& v)
data[idx] = v;
;
template <typename Iterator>
void dummyFunction(Iterator begin, Iterator end)
for (auto it = begin; it != end; it++)
cout << "Before: " << it->a() << "," << it->b() << "t";
it->a() += 1;
it->b() -= 1;
cout << "After: " << it->a() << "," << it->b() << "n";
int main()
vector<LegacyWidgetData> c11, 2, 3, 4, 5, 6;
dummyFunction(c1.begin(), c1.end());
vector<GenericWidgetData<3>> c21, 2, 3, 4, 5, 6, 7, 8, 9;
// dummyFunction(c2.begin(), c2.end()); // Will not compile
return 0;
I have the following assumptions/restrictions:
- I cannot modify the implementation of
LegacyWidgetData
ordummyFunction
- I can add methods to
GenericWidgetData
, and add any iterator adaptors as may be needed.
What I'd like to have is some sort of a iterator adaptor that when applied to any kind of iterator of GenericWidgetData
gives me an iterator that acts like an iterator of LegacyWidgetData
, without any caching/creation of intermediate object involved. Big props if this can be done in compile-time using template meta programming!
templates iterator c++14 template-meta-programming
I have the following MWE:
#include <iostream>
#include <vector>
using namespace std;
class LegacyWidgetData
private:
double _a;
double _b;
public:
LegacyWidgetData()
: _a(0), _b(0)
LegacyWidgetData(const double &a, const double &b)
: _a(a), _b(b)
LegacyWidgetData(const LegacyWidgetData& w)
: _a(w.a()), _b(w.b())
inline double &a()
return _a;
inline double a() const
return _a;
inline double &b()
return _b;
inline double b() const
return _b;
;
template <std::size_t D>
class GenericWidgetData
private:
double data[D];
public:
GenericWidgetData(double a, double b)
data[0] = a;
data[1] = b;
GenericWidgetData(double a, double b, double c)
data[0] = a;
data[1] = b;
data[2] = c;
double get(int idx)
return data[idx];
void set(int idx, const double& v)
data[idx] = v;
;
template <typename Iterator>
void dummyFunction(Iterator begin, Iterator end)
for (auto it = begin; it != end; it++)
cout << "Before: " << it->a() << "," << it->b() << "t";
it->a() += 1;
it->b() -= 1;
cout << "After: " << it->a() << "," << it->b() << "n";
int main()
vector<LegacyWidgetData> c11, 2, 3, 4, 5, 6;
dummyFunction(c1.begin(), c1.end());
vector<GenericWidgetData<3>> c21, 2, 3, 4, 5, 6, 7, 8, 9;
// dummyFunction(c2.begin(), c2.end()); // Will not compile
return 0;
I have the following assumptions/restrictions:
- I cannot modify the implementation of
LegacyWidgetData
ordummyFunction
- I can add methods to
GenericWidgetData
, and add any iterator adaptors as may be needed.
What I'd like to have is some sort of a iterator adaptor that when applied to any kind of iterator of GenericWidgetData
gives me an iterator that acts like an iterator of LegacyWidgetData
, without any caching/creation of intermediate object involved. Big props if this can be done in compile-time using template meta programming!
templates iterator c++14 template-meta-programming
templates iterator c++14 template-meta-programming
edited Nov 14 '18 at 1:22
DeiDei
6,13553354
6,13553354
asked Nov 14 '18 at 0:54
TCSGradTCSGrad
5,379104062
5,379104062
Why would you expect it to compile asdummyFunction
use members functionsa
andb
which does not exists inGenericWidgetData
. It might help to read compiler error message!
– Phil1970
Nov 14 '18 at 1:42
@Phil1970 It might help if you read the question in its entirety
– TCSGrad
Nov 14 '18 at 1:55
Read your question again and tell me where is the question. The purpose of the site is not to write code for other peoples or do their homework.
– Phil1970
Nov 14 '18 at 2:40
add a comment |
Why would you expect it to compile asdummyFunction
use members functionsa
andb
which does not exists inGenericWidgetData
. It might help to read compiler error message!
– Phil1970
Nov 14 '18 at 1:42
@Phil1970 It might help if you read the question in its entirety
– TCSGrad
Nov 14 '18 at 1:55
Read your question again and tell me where is the question. The purpose of the site is not to write code for other peoples or do their homework.
– Phil1970
Nov 14 '18 at 2:40
Why would you expect it to compile as
dummyFunction
use members functions a
and b
which does not exists in GenericWidgetData
. It might help to read compiler error message!– Phil1970
Nov 14 '18 at 1:42
Why would you expect it to compile as
dummyFunction
use members functions a
and b
which does not exists in GenericWidgetData
. It might help to read compiler error message!– Phil1970
Nov 14 '18 at 1:42
@Phil1970 It might help if you read the question in its entirety
– TCSGrad
Nov 14 '18 at 1:55
@Phil1970 It might help if you read the question in its entirety
– TCSGrad
Nov 14 '18 at 1:55
Read your question again and tell me where is the question. The purpose of the site is not to write code for other peoples or do their homework.
– Phil1970
Nov 14 '18 at 2:40
Read your question again and tell me where is the question. The purpose of the site is not to write code for other peoples or do their homework.
– Phil1970
Nov 14 '18 at 2:40
add a comment |
2 Answers
2
active
oldest
votes
What you could do is add a template specialization to GenericWidgetData
for when D == 2
and then implement the .a()
and .b()
functions to match LegacyWidgetData
's interface.
Even if an iterator adapter that could switch at compile-time with some metaprogramming tricks could be written, it would be very complicated to be understood by anyone but its own writer.
You overlooked the restraint that I cannot editdummyFunction
(which is just one of a thousand different functions that accept iterators ofLegacyWidgetData
) - without that restraint, the problem becomes much simpler.
– TCSGrad
Nov 14 '18 at 1:25
1
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization toGenericWidget
forD == 2
that includes member functions.a()
and.b()
to comply withLegacyWidget
's interface.
– DeiDei
Nov 14 '18 at 1:28
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
add a comment |
If you have iterator adaptor, then you would typically need two such objects.
And if you have a lot of those algorithms, then it would make sense to hide the vector inside another class whose begin/end method would returns adaptors instead. Something more or less like that:
templace <std::size_t D> class MyContainer
public:
MyAdaptor<D> begin();
MyAdaptor<D> end();
private:
std::vector<GenericWidgetData<D>> data;
;
However, it might make sense to simply add the appropriate functions to GenericWidgetData
. In that case, you might want to have some specializations so that for example b()
is only available if size is 2 or more etc.
Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData
, then would call a free function.
double& b(LegacyWidgetData &data) return data.b();
const double& b(const LegacyWidgetData &data) return data.b();
And you would then add overloads for GenericWidgetData as appropriate. Using static_assert
for validation might work relatively well in that case:
template <std::size_t D> double& b(GenericWidgetData<D> &widgetData)
static_assert(D > 1, "b is available only if D is big enough");
return widgetData.data[D]; // Or an accessor function to avoid making it public
You would then add the const
variation too.
It is more works but it is more flexible. For example, you can have proper validation of the dimension per function.
Alternatively, another solution is to have extra parameters to your algorithm for the transformation to apply.
template <typename Iterator, typename FA, typename FB>
void dummyFunction(Iterator begin, Iterator end, FA fa, FB fb)
for (auto it = begin; it != end; it++)
cout << "Before: " << fa(*it) << "," << fb(*it) << "t";
fa(*it) += 1;
fa(*it) -= 1;
cout << "After: " << fa(*it) << "," << fb(*it) << "n";
This might seems a lot of work but then you are very flexible. So maybe, you can reconsider which code you want to modify.
It might be better to make such change now and have cleaner code in the future than to create an adaptor or add many functions to GenericWidgetData
that are intended to be used only by the algorithms.
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
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%2f53291653%2fdesign-iterator-adaptor-to-convert-between-unrelated-objects%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
What you could do is add a template specialization to GenericWidgetData
for when D == 2
and then implement the .a()
and .b()
functions to match LegacyWidgetData
's interface.
Even if an iterator adapter that could switch at compile-time with some metaprogramming tricks could be written, it would be very complicated to be understood by anyone but its own writer.
You overlooked the restraint that I cannot editdummyFunction
(which is just one of a thousand different functions that accept iterators ofLegacyWidgetData
) - without that restraint, the problem becomes much simpler.
– TCSGrad
Nov 14 '18 at 1:25
1
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization toGenericWidget
forD == 2
that includes member functions.a()
and.b()
to comply withLegacyWidget
's interface.
– DeiDei
Nov 14 '18 at 1:28
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
add a comment |
What you could do is add a template specialization to GenericWidgetData
for when D == 2
and then implement the .a()
and .b()
functions to match LegacyWidgetData
's interface.
Even if an iterator adapter that could switch at compile-time with some metaprogramming tricks could be written, it would be very complicated to be understood by anyone but its own writer.
You overlooked the restraint that I cannot editdummyFunction
(which is just one of a thousand different functions that accept iterators ofLegacyWidgetData
) - without that restraint, the problem becomes much simpler.
– TCSGrad
Nov 14 '18 at 1:25
1
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization toGenericWidget
forD == 2
that includes member functions.a()
and.b()
to comply withLegacyWidget
's interface.
– DeiDei
Nov 14 '18 at 1:28
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
add a comment |
What you could do is add a template specialization to GenericWidgetData
for when D == 2
and then implement the .a()
and .b()
functions to match LegacyWidgetData
's interface.
Even if an iterator adapter that could switch at compile-time with some metaprogramming tricks could be written, it would be very complicated to be understood by anyone but its own writer.
What you could do is add a template specialization to GenericWidgetData
for when D == 2
and then implement the .a()
and .b()
functions to match LegacyWidgetData
's interface.
Even if an iterator adapter that could switch at compile-time with some metaprogramming tricks could be written, it would be very complicated to be understood by anyone but its own writer.
edited Nov 14 '18 at 1:38
answered Nov 14 '18 at 1:21
DeiDeiDeiDei
6,13553354
6,13553354
You overlooked the restraint that I cannot editdummyFunction
(which is just one of a thousand different functions that accept iterators ofLegacyWidgetData
) - without that restraint, the problem becomes much simpler.
– TCSGrad
Nov 14 '18 at 1:25
1
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization toGenericWidget
forD == 2
that includes member functions.a()
and.b()
to comply withLegacyWidget
's interface.
– DeiDei
Nov 14 '18 at 1:28
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
add a comment |
You overlooked the restraint that I cannot editdummyFunction
(which is just one of a thousand different functions that accept iterators ofLegacyWidgetData
) - without that restraint, the problem becomes much simpler.
– TCSGrad
Nov 14 '18 at 1:25
1
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization toGenericWidget
forD == 2
that includes member functions.a()
and.b()
to comply withLegacyWidget
's interface.
– DeiDei
Nov 14 '18 at 1:28
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
You overlooked the restraint that I cannot edit
dummyFunction
(which is just one of a thousand different functions that accept iterators of LegacyWidgetData
) - without that restraint, the problem becomes much simpler.– TCSGrad
Nov 14 '18 at 1:25
You overlooked the restraint that I cannot edit
dummyFunction
(which is just one of a thousand different functions that accept iterators of LegacyWidgetData
) - without that restraint, the problem becomes much simpler.– TCSGrad
Nov 14 '18 at 1:25
1
1
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization to
GenericWidget
for D == 2
that includes member functions .a()
and .b()
to comply with LegacyWidget
's interface.– DeiDei
Nov 14 '18 at 1:28
@TCSGrad Ah, apologies. Well, you're in quite a pickle then. You could probably add a templare specialization to
GenericWidget
for D == 2
that includes member functions .a()
and .b()
to comply with LegacyWidget
's interface.– DeiDei
Nov 14 '18 at 1:28
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
That actually makes sense for this toy example, but not for my actual code base (which basically wraps the iterator in a another class which has some custom properties) - seems I have to distill the problem into a better example without simplifying it too much! If you can edit you answer to reflect your comment, I'll accept it and work on a better MWE for a different question.
– TCSGrad
Nov 14 '18 at 1:32
add a comment |
If you have iterator adaptor, then you would typically need two such objects.
And if you have a lot of those algorithms, then it would make sense to hide the vector inside another class whose begin/end method would returns adaptors instead. Something more or less like that:
templace <std::size_t D> class MyContainer
public:
MyAdaptor<D> begin();
MyAdaptor<D> end();
private:
std::vector<GenericWidgetData<D>> data;
;
However, it might make sense to simply add the appropriate functions to GenericWidgetData
. In that case, you might want to have some specializations so that for example b()
is only available if size is 2 or more etc.
Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData
, then would call a free function.
double& b(LegacyWidgetData &data) return data.b();
const double& b(const LegacyWidgetData &data) return data.b();
And you would then add overloads for GenericWidgetData as appropriate. Using static_assert
for validation might work relatively well in that case:
template <std::size_t D> double& b(GenericWidgetData<D> &widgetData)
static_assert(D > 1, "b is available only if D is big enough");
return widgetData.data[D]; // Or an accessor function to avoid making it public
You would then add the const
variation too.
It is more works but it is more flexible. For example, you can have proper validation of the dimension per function.
Alternatively, another solution is to have extra parameters to your algorithm for the transformation to apply.
template <typename Iterator, typename FA, typename FB>
void dummyFunction(Iterator begin, Iterator end, FA fa, FB fb)
for (auto it = begin; it != end; it++)
cout << "Before: " << fa(*it) << "," << fb(*it) << "t";
fa(*it) += 1;
fa(*it) -= 1;
cout << "After: " << fa(*it) << "," << fb(*it) << "n";
This might seems a lot of work but then you are very flexible. So maybe, you can reconsider which code you want to modify.
It might be better to make such change now and have cleaner code in the future than to create an adaptor or add many functions to GenericWidgetData
that are intended to be used only by the algorithms.
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
add a comment |
If you have iterator adaptor, then you would typically need two such objects.
And if you have a lot of those algorithms, then it would make sense to hide the vector inside another class whose begin/end method would returns adaptors instead. Something more or less like that:
templace <std::size_t D> class MyContainer
public:
MyAdaptor<D> begin();
MyAdaptor<D> end();
private:
std::vector<GenericWidgetData<D>> data;
;
However, it might make sense to simply add the appropriate functions to GenericWidgetData
. In that case, you might want to have some specializations so that for example b()
is only available if size is 2 or more etc.
Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData
, then would call a free function.
double& b(LegacyWidgetData &data) return data.b();
const double& b(const LegacyWidgetData &data) return data.b();
And you would then add overloads for GenericWidgetData as appropriate. Using static_assert
for validation might work relatively well in that case:
template <std::size_t D> double& b(GenericWidgetData<D> &widgetData)
static_assert(D > 1, "b is available only if D is big enough");
return widgetData.data[D]; // Or an accessor function to avoid making it public
You would then add the const
variation too.
It is more works but it is more flexible. For example, you can have proper validation of the dimension per function.
Alternatively, another solution is to have extra parameters to your algorithm for the transformation to apply.
template <typename Iterator, typename FA, typename FB>
void dummyFunction(Iterator begin, Iterator end, FA fa, FB fb)
for (auto it = begin; it != end; it++)
cout << "Before: " << fa(*it) << "," << fb(*it) << "t";
fa(*it) += 1;
fa(*it) -= 1;
cout << "After: " << fa(*it) << "," << fb(*it) << "n";
This might seems a lot of work but then you are very flexible. So maybe, you can reconsider which code you want to modify.
It might be better to make such change now and have cleaner code in the future than to create an adaptor or add many functions to GenericWidgetData
that are intended to be used only by the algorithms.
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
add a comment |
If you have iterator adaptor, then you would typically need two such objects.
And if you have a lot of those algorithms, then it would make sense to hide the vector inside another class whose begin/end method would returns adaptors instead. Something more or less like that:
templace <std::size_t D> class MyContainer
public:
MyAdaptor<D> begin();
MyAdaptor<D> end();
private:
std::vector<GenericWidgetData<D>> data;
;
However, it might make sense to simply add the appropriate functions to GenericWidgetData
. In that case, you might want to have some specializations so that for example b()
is only available if size is 2 or more etc.
Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData
, then would call a free function.
double& b(LegacyWidgetData &data) return data.b();
const double& b(const LegacyWidgetData &data) return data.b();
And you would then add overloads for GenericWidgetData as appropriate. Using static_assert
for validation might work relatively well in that case:
template <std::size_t D> double& b(GenericWidgetData<D> &widgetData)
static_assert(D > 1, "b is available only if D is big enough");
return widgetData.data[D]; // Or an accessor function to avoid making it public
You would then add the const
variation too.
It is more works but it is more flexible. For example, you can have proper validation of the dimension per function.
Alternatively, another solution is to have extra parameters to your algorithm for the transformation to apply.
template <typename Iterator, typename FA, typename FB>
void dummyFunction(Iterator begin, Iterator end, FA fa, FB fb)
for (auto it = begin; it != end; it++)
cout << "Before: " << fa(*it) << "," << fb(*it) << "t";
fa(*it) += 1;
fa(*it) -= 1;
cout << "After: " << fa(*it) << "," << fb(*it) << "n";
This might seems a lot of work but then you are very flexible. So maybe, you can reconsider which code you want to modify.
It might be better to make such change now and have cleaner code in the future than to create an adaptor or add many functions to GenericWidgetData
that are intended to be used only by the algorithms.
If you have iterator adaptor, then you would typically need two such objects.
And if you have a lot of those algorithms, then it would make sense to hide the vector inside another class whose begin/end method would returns adaptors instead. Something more or less like that:
templace <std::size_t D> class MyContainer
public:
MyAdaptor<D> begin();
MyAdaptor<D> end();
private:
std::vector<GenericWidgetData<D>> data;
;
However, it might make sense to simply add the appropriate functions to GenericWidgetData
. In that case, you might want to have some specializations so that for example b()
is only available if size is 2 or more etc.
Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData
, then would call a free function.
double& b(LegacyWidgetData &data) return data.b();
const double& b(const LegacyWidgetData &data) return data.b();
And you would then add overloads for GenericWidgetData as appropriate. Using static_assert
for validation might work relatively well in that case:
template <std::size_t D> double& b(GenericWidgetData<D> &widgetData)
static_assert(D > 1, "b is available only if D is big enough");
return widgetData.data[D]; // Or an accessor function to avoid making it public
You would then add the const
variation too.
It is more works but it is more flexible. For example, you can have proper validation of the dimension per function.
Alternatively, another solution is to have extra parameters to your algorithm for the transformation to apply.
template <typename Iterator, typename FA, typename FB>
void dummyFunction(Iterator begin, Iterator end, FA fa, FB fb)
for (auto it = begin; it != end; it++)
cout << "Before: " << fa(*it) << "," << fb(*it) << "t";
fa(*it) += 1;
fa(*it) -= 1;
cout << "After: " << fa(*it) << "," << fb(*it) << "n";
This might seems a lot of work but then you are very flexible. So maybe, you can reconsider which code you want to modify.
It might be better to make such change now and have cleaner code in the future than to create an adaptor or add many functions to GenericWidgetData
that are intended to be used only by the algorithms.
answered Nov 14 '18 at 2:24
Phil1970Phil1970
1,313189
1,313189
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
add a comment |
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
"Neverthless, the best solution would probably be to modify the 1000 functions so that instead of accessing directly members of LegacyWidgetData, then would call a free function." I take it you've never worked in a code base in which certain parts are read-only ?
– TCSGrad
Nov 14 '18 at 16:04
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
If your software company wrote the code and the code is not adequate anymore, then improve it. If you use a lot your library of 1000 functions, then making them easier to use would pay by itself in simplicity of writing new code and reduced maintenance. Unit testing is a good way to ensure you don't introduce new bugs in your code but given that your change are trivial, maybe you could make a copy of the code and change it. With find and replace you might be able to update the library in a day or 2.
– Phil1970
Nov 15 '18 at 5:43
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%2f53291653%2fdesign-iterator-adaptor-to-convert-between-unrelated-objects%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
Why would you expect it to compile as
dummyFunction
use members functionsa
andb
which does not exists inGenericWidgetData
. It might help to read compiler error message!– Phil1970
Nov 14 '18 at 1:42
@Phil1970 It might help if you read the question in its entirety
– TCSGrad
Nov 14 '18 at 1:55
Read your question again and tell me where is the question. The purpose of the site is not to write code for other peoples or do their homework.
– Phil1970
Nov 14 '18 at 2:40