C++ Templated single value container (std::any) with meta data
My intention is to implement a single value container which stores all possible types, like QVariant
or others does. I tried to take advantage of std::any
which gives a type safe container for the same purpose. Additionally I would like to store some meta data (timestamps mostly) which refer to target value.
I came up so far with two solutions which does not work properly. The class template version Value
works but the interface does not fit properly in my opinion. See the first get
function for an example. One need to know which type is returned on invocation. auto
could help, but not in all situations.
The second solution has a pretty nice interface, like QVariant
. See the access function get
which returns LateValue
. After calling this function one can dig deeper for the stored type and so on. Problem here is whenever I put this stuff into a library the template methods (getter and constructor) do not get instantiated. One can do this manually with the getter method but not with the constructor, it is simply not possible.
#include <any>
#include <memory>
#include <iostream>
class Time {
int m_a, m_b;
public:
Time(int a, int b) : m_a(a), m_b(b) {}
int a() const { return m_a; }
int b() const { return m_b; }
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
os << time.a() << ' ' << time.b();
return os;
}
};
template<typename T>
class Value {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
explicit Value(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
T get() const {
return std::any_cast<T>(m_p->value);
}
};
class LateValue {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
template<typename T>
LateValue(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
template<typename T>
T get() const {
return std::any_cast<T>(m_p->value);
};
Here is a simple test program. Note that the above code goes into the same file.
template<typename T>
Value<T> get() {
return Value<T>(1.2f);
}
LateValue get() {
return LateValue(1.2f);
}
int main() {
Value<int> v0(1);
Value<float> v1(1.234f);
Value<Time> v2(Time(1, 2));
LateValue l0(1);
LateValue l1(1.234f);
LateValue l2(Time(1, 2));
std::cout << v0.get() << ' '
<< v1.get() << ' '
<< v2.get() << 'n'
<< l0.get<int>() << ' '
<< l1.get<float>() << ' '
<< l2.get<Time>() << 'n';
auto value = get<float>();
std::cout << " value is " << value.get() << 'n';
// l2.get<double>(); <--- exception: bad_any_cast (ok to me)
return 0;
}
The output is simply as in code, because it is working (single file!):
1 1.234 1 2
1 1.234 1 2
value is 1.2
So the question is: How to improve the implementation to have a nice interface with simplicity of template parameter? (I try to overcome the necessity to implement a get method for every supported type.)
c++ template c++17
New contributor
add a comment |
My intention is to implement a single value container which stores all possible types, like QVariant
or others does. I tried to take advantage of std::any
which gives a type safe container for the same purpose. Additionally I would like to store some meta data (timestamps mostly) which refer to target value.
I came up so far with two solutions which does not work properly. The class template version Value
works but the interface does not fit properly in my opinion. See the first get
function for an example. One need to know which type is returned on invocation. auto
could help, but not in all situations.
The second solution has a pretty nice interface, like QVariant
. See the access function get
which returns LateValue
. After calling this function one can dig deeper for the stored type and so on. Problem here is whenever I put this stuff into a library the template methods (getter and constructor) do not get instantiated. One can do this manually with the getter method but not with the constructor, it is simply not possible.
#include <any>
#include <memory>
#include <iostream>
class Time {
int m_a, m_b;
public:
Time(int a, int b) : m_a(a), m_b(b) {}
int a() const { return m_a; }
int b() const { return m_b; }
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
os << time.a() << ' ' << time.b();
return os;
}
};
template<typename T>
class Value {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
explicit Value(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
T get() const {
return std::any_cast<T>(m_p->value);
}
};
class LateValue {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
template<typename T>
LateValue(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
template<typename T>
T get() const {
return std::any_cast<T>(m_p->value);
};
Here is a simple test program. Note that the above code goes into the same file.
template<typename T>
Value<T> get() {
return Value<T>(1.2f);
}
LateValue get() {
return LateValue(1.2f);
}
int main() {
Value<int> v0(1);
Value<float> v1(1.234f);
Value<Time> v2(Time(1, 2));
LateValue l0(1);
LateValue l1(1.234f);
LateValue l2(Time(1, 2));
std::cout << v0.get() << ' '
<< v1.get() << ' '
<< v2.get() << 'n'
<< l0.get<int>() << ' '
<< l1.get<float>() << ' '
<< l2.get<Time>() << 'n';
auto value = get<float>();
std::cout << " value is " << value.get() << 'n';
// l2.get<double>(); <--- exception: bad_any_cast (ok to me)
return 0;
}
The output is simply as in code, because it is working (single file!):
1 1.234 1 2
1 1.234 1 2
value is 1.2
So the question is: How to improve the implementation to have a nice interface with simplicity of template parameter? (I try to overcome the necessity to implement a get method for every supported type.)
c++ template c++17
New contributor
This seems to be asking how to work around a specific language issue? I'm also not sure we have enough context about howValue
andLateValue
are actually used to comment on design.
– user673679
yesterday
Looks likeQVariant
is a poor mansstd::any
with the addition of a poor mansboost::lexecal_cast()
built into the interface. To me it seems like you can implement a better version ofQVariant
with these two.
– Martin York
yesterday
Value
andLateValue
are identical, except thatLateValue
is missing a closing curly brace}
near the end of the class. If you want them to do different things, you'll have to give them different code.
– Quuxplusone
1 hour ago
add a comment |
My intention is to implement a single value container which stores all possible types, like QVariant
or others does. I tried to take advantage of std::any
which gives a type safe container for the same purpose. Additionally I would like to store some meta data (timestamps mostly) which refer to target value.
I came up so far with two solutions which does not work properly. The class template version Value
works but the interface does not fit properly in my opinion. See the first get
function for an example. One need to know which type is returned on invocation. auto
could help, but not in all situations.
The second solution has a pretty nice interface, like QVariant
. See the access function get
which returns LateValue
. After calling this function one can dig deeper for the stored type and so on. Problem here is whenever I put this stuff into a library the template methods (getter and constructor) do not get instantiated. One can do this manually with the getter method but not with the constructor, it is simply not possible.
#include <any>
#include <memory>
#include <iostream>
class Time {
int m_a, m_b;
public:
Time(int a, int b) : m_a(a), m_b(b) {}
int a() const { return m_a; }
int b() const { return m_b; }
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
os << time.a() << ' ' << time.b();
return os;
}
};
template<typename T>
class Value {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
explicit Value(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
T get() const {
return std::any_cast<T>(m_p->value);
}
};
class LateValue {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
template<typename T>
LateValue(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
template<typename T>
T get() const {
return std::any_cast<T>(m_p->value);
};
Here is a simple test program. Note that the above code goes into the same file.
template<typename T>
Value<T> get() {
return Value<T>(1.2f);
}
LateValue get() {
return LateValue(1.2f);
}
int main() {
Value<int> v0(1);
Value<float> v1(1.234f);
Value<Time> v2(Time(1, 2));
LateValue l0(1);
LateValue l1(1.234f);
LateValue l2(Time(1, 2));
std::cout << v0.get() << ' '
<< v1.get() << ' '
<< v2.get() << 'n'
<< l0.get<int>() << ' '
<< l1.get<float>() << ' '
<< l2.get<Time>() << 'n';
auto value = get<float>();
std::cout << " value is " << value.get() << 'n';
// l2.get<double>(); <--- exception: bad_any_cast (ok to me)
return 0;
}
The output is simply as in code, because it is working (single file!):
1 1.234 1 2
1 1.234 1 2
value is 1.2
So the question is: How to improve the implementation to have a nice interface with simplicity of template parameter? (I try to overcome the necessity to implement a get method for every supported type.)
c++ template c++17
New contributor
My intention is to implement a single value container which stores all possible types, like QVariant
or others does. I tried to take advantage of std::any
which gives a type safe container for the same purpose. Additionally I would like to store some meta data (timestamps mostly) which refer to target value.
I came up so far with two solutions which does not work properly. The class template version Value
works but the interface does not fit properly in my opinion. See the first get
function for an example. One need to know which type is returned on invocation. auto
could help, but not in all situations.
The second solution has a pretty nice interface, like QVariant
. See the access function get
which returns LateValue
. After calling this function one can dig deeper for the stored type and so on. Problem here is whenever I put this stuff into a library the template methods (getter and constructor) do not get instantiated. One can do this manually with the getter method but not with the constructor, it is simply not possible.
#include <any>
#include <memory>
#include <iostream>
class Time {
int m_a, m_b;
public:
Time(int a, int b) : m_a(a), m_b(b) {}
int a() const { return m_a; }
int b() const { return m_b; }
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
os << time.a() << ' ' << time.b();
return os;
}
};
template<typename T>
class Value {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
explicit Value(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
T get() const {
return std::any_cast<T>(m_p->value);
}
};
class LateValue {
struct Impl {
std::any value;
};
std::unique_ptr<Impl> m_p;
public:
template<typename T>
LateValue(const T &value) : m_p(std::make_unique<Impl>()) {
m_p->value = std::make_any<T>(value);
}
template<typename T>
T get() const {
return std::any_cast<T>(m_p->value);
};
Here is a simple test program. Note that the above code goes into the same file.
template<typename T>
Value<T> get() {
return Value<T>(1.2f);
}
LateValue get() {
return LateValue(1.2f);
}
int main() {
Value<int> v0(1);
Value<float> v1(1.234f);
Value<Time> v2(Time(1, 2));
LateValue l0(1);
LateValue l1(1.234f);
LateValue l2(Time(1, 2));
std::cout << v0.get() << ' '
<< v1.get() << ' '
<< v2.get() << 'n'
<< l0.get<int>() << ' '
<< l1.get<float>() << ' '
<< l2.get<Time>() << 'n';
auto value = get<float>();
std::cout << " value is " << value.get() << 'n';
// l2.get<double>(); <--- exception: bad_any_cast (ok to me)
return 0;
}
The output is simply as in code, because it is working (single file!):
1 1.234 1 2
1 1.234 1 2
value is 1.2
So the question is: How to improve the implementation to have a nice interface with simplicity of template parameter? (I try to overcome the necessity to implement a get method for every supported type.)
c++ template c++17
c++ template c++17
New contributor
New contributor
edited yesterday
user673679
2,3781925
2,3781925
New contributor
asked yesterday
maxik
9913
9913
New contributor
New contributor
This seems to be asking how to work around a specific language issue? I'm also not sure we have enough context about howValue
andLateValue
are actually used to comment on design.
– user673679
yesterday
Looks likeQVariant
is a poor mansstd::any
with the addition of a poor mansboost::lexecal_cast()
built into the interface. To me it seems like you can implement a better version ofQVariant
with these two.
– Martin York
yesterday
Value
andLateValue
are identical, except thatLateValue
is missing a closing curly brace}
near the end of the class. If you want them to do different things, you'll have to give them different code.
– Quuxplusone
1 hour ago
add a comment |
This seems to be asking how to work around a specific language issue? I'm also not sure we have enough context about howValue
andLateValue
are actually used to comment on design.
– user673679
yesterday
Looks likeQVariant
is a poor mansstd::any
with the addition of a poor mansboost::lexecal_cast()
built into the interface. To me it seems like you can implement a better version ofQVariant
with these two.
– Martin York
yesterday
Value
andLateValue
are identical, except thatLateValue
is missing a closing curly brace}
near the end of the class. If you want them to do different things, you'll have to give them different code.
– Quuxplusone
1 hour ago
This seems to be asking how to work around a specific language issue? I'm also not sure we have enough context about how
Value
and LateValue
are actually used to comment on design.– user673679
yesterday
This seems to be asking how to work around a specific language issue? I'm also not sure we have enough context about how
Value
and LateValue
are actually used to comment on design.– user673679
yesterday
Looks like
QVariant
is a poor mans std::any
with the addition of a poor mans boost::lexecal_cast()
built into the interface. To me it seems like you can implement a better version of QVariant
with these two.– Martin York
yesterday
Looks like
QVariant
is a poor mans std::any
with the addition of a poor mans boost::lexecal_cast()
built into the interface. To me it seems like you can implement a better version of QVariant
with these two.– Martin York
yesterday
Value
and LateValue
are identical, except that LateValue
is missing a closing curly brace }
near the end of the class. If you want them to do different things, you'll have to give them different code.– Quuxplusone
1 hour ago
Value
and LateValue
are identical, except that LateValue
is missing a closing curly brace }
near the end of the class. If you want them to do different things, you'll have to give them different code.– Quuxplusone
1 hour ago
add a comment |
1 Answer
1
active
oldest
votes
So it looks like you want a type where you can add an object of any type. But you want the ability to pull that object out as any other type (with potentially a testing function that allows you to test the type).
class LokiValue
{
std::any value;
public:
template<typename T>
void put(T const& input) {
// Put stuff in value of type T
value = input;
}
template<typename S, typename T = S>
T get() {
// Get stuff in value that is of type S
// but return a value of type T
// by default S and T are the same type.
if (!value.has_value()) {
throw MyException("Message 1");
}
// This will throw if:
// * S is not the type stored.
// * If S is not convertible to T
return boost::lexical_cast<T>(std::any_cast<S>(value));
}
template<typename S, typename T>
bool check() {
// Check stuff in value is of type S and can be converted
// into an object of type T
if (!value.has_value()) {
return false;
}
try {
boost::lexical_cast<T>(std::any_cast<S>(value));
}
catch(...) {
return false;
}
return true;
}
};
Now this does not solve your problem directly as:
l2.get<double, Time>(); // This will still throw as Time is not convertable
// to a double yet. But we can simply change the
// the output format of time so it is compatable with
// the double stream input.
So what do we have to change to make them compatible?
class Time {
// STUFF
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
return os << time.m_a << '.' << time.m_b;
// ^^^ Just change this to a dot
// The output of Time is compatible with
// the input of double,
}
};
So now we have:
int main() {
LokiValue l2;
l2.put(Time(1, 2)); // I was lazy and did not add a constructor.
// I'll leave that to you.
l2.get<double, Time>();
}
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
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: "196"
};
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
});
}
});
maxik is a new contributor. Be nice, and check out our Code of Conduct.
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%2fcodereview.stackexchange.com%2fquestions%2f210866%2fc-templated-single-value-container-stdany-with-meta-data%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
So it looks like you want a type where you can add an object of any type. But you want the ability to pull that object out as any other type (with potentially a testing function that allows you to test the type).
class LokiValue
{
std::any value;
public:
template<typename T>
void put(T const& input) {
// Put stuff in value of type T
value = input;
}
template<typename S, typename T = S>
T get() {
// Get stuff in value that is of type S
// but return a value of type T
// by default S and T are the same type.
if (!value.has_value()) {
throw MyException("Message 1");
}
// This will throw if:
// * S is not the type stored.
// * If S is not convertible to T
return boost::lexical_cast<T>(std::any_cast<S>(value));
}
template<typename S, typename T>
bool check() {
// Check stuff in value is of type S and can be converted
// into an object of type T
if (!value.has_value()) {
return false;
}
try {
boost::lexical_cast<T>(std::any_cast<S>(value));
}
catch(...) {
return false;
}
return true;
}
};
Now this does not solve your problem directly as:
l2.get<double, Time>(); // This will still throw as Time is not convertable
// to a double yet. But we can simply change the
// the output format of time so it is compatable with
// the double stream input.
So what do we have to change to make them compatible?
class Time {
// STUFF
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
return os << time.m_a << '.' << time.m_b;
// ^^^ Just change this to a dot
// The output of Time is compatible with
// the input of double,
}
};
So now we have:
int main() {
LokiValue l2;
l2.put(Time(1, 2)); // I was lazy and did not add a constructor.
// I'll leave that to you.
l2.get<double, Time>();
}
add a comment |
So it looks like you want a type where you can add an object of any type. But you want the ability to pull that object out as any other type (with potentially a testing function that allows you to test the type).
class LokiValue
{
std::any value;
public:
template<typename T>
void put(T const& input) {
// Put stuff in value of type T
value = input;
}
template<typename S, typename T = S>
T get() {
// Get stuff in value that is of type S
// but return a value of type T
// by default S and T are the same type.
if (!value.has_value()) {
throw MyException("Message 1");
}
// This will throw if:
// * S is not the type stored.
// * If S is not convertible to T
return boost::lexical_cast<T>(std::any_cast<S>(value));
}
template<typename S, typename T>
bool check() {
// Check stuff in value is of type S and can be converted
// into an object of type T
if (!value.has_value()) {
return false;
}
try {
boost::lexical_cast<T>(std::any_cast<S>(value));
}
catch(...) {
return false;
}
return true;
}
};
Now this does not solve your problem directly as:
l2.get<double, Time>(); // This will still throw as Time is not convertable
// to a double yet. But we can simply change the
// the output format of time so it is compatable with
// the double stream input.
So what do we have to change to make them compatible?
class Time {
// STUFF
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
return os << time.m_a << '.' << time.m_b;
// ^^^ Just change this to a dot
// The output of Time is compatible with
// the input of double,
}
};
So now we have:
int main() {
LokiValue l2;
l2.put(Time(1, 2)); // I was lazy and did not add a constructor.
// I'll leave that to you.
l2.get<double, Time>();
}
add a comment |
So it looks like you want a type where you can add an object of any type. But you want the ability to pull that object out as any other type (with potentially a testing function that allows you to test the type).
class LokiValue
{
std::any value;
public:
template<typename T>
void put(T const& input) {
// Put stuff in value of type T
value = input;
}
template<typename S, typename T = S>
T get() {
// Get stuff in value that is of type S
// but return a value of type T
// by default S and T are the same type.
if (!value.has_value()) {
throw MyException("Message 1");
}
// This will throw if:
// * S is not the type stored.
// * If S is not convertible to T
return boost::lexical_cast<T>(std::any_cast<S>(value));
}
template<typename S, typename T>
bool check() {
// Check stuff in value is of type S and can be converted
// into an object of type T
if (!value.has_value()) {
return false;
}
try {
boost::lexical_cast<T>(std::any_cast<S>(value));
}
catch(...) {
return false;
}
return true;
}
};
Now this does not solve your problem directly as:
l2.get<double, Time>(); // This will still throw as Time is not convertable
// to a double yet. But we can simply change the
// the output format of time so it is compatable with
// the double stream input.
So what do we have to change to make them compatible?
class Time {
// STUFF
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
return os << time.m_a << '.' << time.m_b;
// ^^^ Just change this to a dot
// The output of Time is compatible with
// the input of double,
}
};
So now we have:
int main() {
LokiValue l2;
l2.put(Time(1, 2)); // I was lazy and did not add a constructor.
// I'll leave that to you.
l2.get<double, Time>();
}
So it looks like you want a type where you can add an object of any type. But you want the ability to pull that object out as any other type (with potentially a testing function that allows you to test the type).
class LokiValue
{
std::any value;
public:
template<typename T>
void put(T const& input) {
// Put stuff in value of type T
value = input;
}
template<typename S, typename T = S>
T get() {
// Get stuff in value that is of type S
// but return a value of type T
// by default S and T are the same type.
if (!value.has_value()) {
throw MyException("Message 1");
}
// This will throw if:
// * S is not the type stored.
// * If S is not convertible to T
return boost::lexical_cast<T>(std::any_cast<S>(value));
}
template<typename S, typename T>
bool check() {
// Check stuff in value is of type S and can be converted
// into an object of type T
if (!value.has_value()) {
return false;
}
try {
boost::lexical_cast<T>(std::any_cast<S>(value));
}
catch(...) {
return false;
}
return true;
}
};
Now this does not solve your problem directly as:
l2.get<double, Time>(); // This will still throw as Time is not convertable
// to a double yet. But we can simply change the
// the output format of time so it is compatable with
// the double stream input.
So what do we have to change to make them compatible?
class Time {
// STUFF
friend std::ostream &operator<<(std::ostream &os, const Time &time) noexcept {
return os << time.m_a << '.' << time.m_b;
// ^^^ Just change this to a dot
// The output of Time is compatible with
// the input of double,
}
};
So now we have:
int main() {
LokiValue l2;
l2.put(Time(1, 2)); // I was lazy and did not add a constructor.
// I'll leave that to you.
l2.get<double, Time>();
}
answered yesterday
Martin York
72.7k483261
72.7k483261
add a comment |
add a comment |
maxik is a new contributor. Be nice, and check out our Code of Conduct.
maxik is a new contributor. Be nice, and check out our Code of Conduct.
maxik is a new contributor. Be nice, and check out our Code of Conduct.
maxik is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- 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.
Use MathJax to format equations. MathJax reference.
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%2fcodereview.stackexchange.com%2fquestions%2f210866%2fc-templated-single-value-container-stdany-with-meta-data%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
This seems to be asking how to work around a specific language issue? I'm also not sure we have enough context about how
Value
andLateValue
are actually used to comment on design.– user673679
yesterday
Looks like
QVariant
is a poor mansstd::any
with the addition of a poor mansboost::lexecal_cast()
built into the interface. To me it seems like you can implement a better version ofQVariant
with these two.– Martin York
yesterday
Value
andLateValue
are identical, except thatLateValue
is missing a closing curly brace}
near the end of the class. If you want them to do different things, you'll have to give them different code.– Quuxplusone
1 hour ago