Why is Assert::AreSame() failing?
C++ class to be tested:
template <typename T>
class XPtr
{
private:
T* p;
public:
XPtr(T* ptr) {
p = ptr;
}
XPtr(const XPtr& ptr) {
p = ptr.p;
}
T* operator&() {
return p;
}
// The following declaration compiles but still
// is it the correct way of declaring friend function?
template<typename T>
friend std::wstring getString(const XPtr<T>& p);
};
template<typename T>
std::wstring getString(const XPtr<T>& p) {
std::wstringstream ss;
ss << L"{" << p.p;
if (p.p != 0) { ss << L"," << *p.p; }
ss << L"}";
return ss.str();
}
Native C++ Unit Test is as follows:
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace Microsoft {
namespace VisualStudio {
namespace CppUnitTestFramework {
//Actually I would like to specialize for XPtr<T> instead of XPtr<int>,
//how to do it?
template<>
static std::wstring ToString<XPtr<int> >(const class XPtr<int> & t)
{ return getString<int>(t); }
}
}
}
namespace TestRCPtr1
{
TEST_CLASS(UnitTest1)
{
public:
TEST_METHOD(TestMethod6)
{
XPtr<int> p1(new int(1));
XPtr<int> p2(p1);
Assert::AreEqual(&p1, &p2); // Test passes
Assert::AreSame(p1, p2); // Test fails, see below for error message
}
};
}
Result Message: Assert failed. Expected:<{000000001BE465D0,1}> Actual:<{000000001BE465D0,1}>
Question 1: As per my understanding Assert::AreSame() should compare with logic &p1==&p2 and pass successfully. What is going wrong here?
Question 2: How to specialize Microsoft::VisualStudio::CppUnitTestFramework::ToString() (see at top of unit test code) for XPtr<T> instead of XPtr<int> ?
Related
I am new authoring C++/WinRT runtime classes, and I was requested to overload the subscript operator ([ ]) for a runtime class Parameter. The class Parameter contains an IMap<hstring, IInspectable> that stores a set of parameters indexed by the parameter name.
Here is the code:
namespace winrt::Parameter::implementation
{
using namespace winrt;
using namespace Windows::Foundation::Collections;
struct Parameter : ParameterT<Parameter>
{
private:
IMap<hstring, IInspectable> m_Parameters{ nullptr };
public:
Parameter() { m_Parameters = single_threaded_map<hstring, IInspectable>(); }
~Parameter() {};
IInspectable& operator[](const hstring& key)
{
if (!m_Parameters.HasKey(key))
{
m_Parameters.Insert(key, {});
}
return m_Parameters.Lookup(key);
}
IInspectable const& operator[](const hstring& key) const
{
if (!m_Parameters.HasKey(key))
{
m_Parameters.Insert(key, {});
}
return m_Parameters.Lookup(key);
}
};
}
namespace winrt::Parameter::factory_implementation
{
struct Parameter : ParameterT<Parameter, implementation::Parameter>
{
};
}
The code above compiles with no errors, but I get the below error when I try to consume the Parameter code in a UWP C# test App:
Parameter parameter = new Parameter();
const string V = "test";
parameter[V] = "any test value";
string test = parameter[V];
Error CS0021 Cannot apply indexing with [ ] to an expression of type 'Parameter'
Does anyone have any ideas on what I am missing here?
The problem seems to be with the C++/WinRT version because this other similar code using standard C++/17 works as expected.
class Parameter
{
private:
std::map<std::string, std::any> m_Parameter{};
public:
std::any& operator[](const std::string& name);
};
std::any& Parameter::operator[](const std::string& key)
{
if (m_Parameter.find(key) == m_Parameter.end())
{
m_Parameter.insert({ key, {} });
}
return m_Parameter.at(key);
}
int main()
{
Parameter parameter{};
parameter["test"] = 'b';
parameter["other test"] = std::string("other test value");
std::cout << std::any_cast<std::string>(parameter["other test"]) << '\n';
std::cout << std::any_cast<char>(parameter["test"]) << '\n';
return 0;
}
Assume we are working with Clang strictly. No other compiler is being used. Also note that Clang supports CXX ABI.
We are using C++14.
Normally, we would get demangled class name like so:
#include <cxxabi.h>
class GoodClass {
public:
virtual const char *foo() const noexcept;
}
const char *
GoodClass::foo() const noexcept
{
// Naive implementation, not gonna' check any errors and stuff.
int32_t status = 0;
return abi::__cxa_demangle(typeid(*this).name(), 0, 0, &status);
}
This method will help us when we need class names of public subclasses of this class:
class SomeSubclassOfGoodClass : public GoodClass { }
SomeSubclassOfGoodClass object;
std::cout << object.foo(); // prints "SomeSubclassOfGoodClass"
However, in static methods, we could not use this since there is no instance. Therefore, it is impossible to serve an object to the typeid directive.
The examplary method serves well (with polymorphism), however it needs an instance to operate. This would involve problems about OO (such as constructors).
What would you do in a situation like this?
Thank you for your attention.
The use of demangle needs a little work. At the moment you have a memory leak.
Here's one way to solve that:
#include <cxxabi.h>
#include <memory>
#include <iostream>
#include <string>
#include <typeinfo>
#include <typeindex>
#include <cassert>
#include <stdexcept>
struct demangled_string
{
using ptr_type = std::unique_ptr<char, void(*)(void*)>;
demangled_string(ptr_type&& ptr) noexcept;
const char* c_str() const;
operator std::string() const;
std::ostream& write(std::ostream& os) const;
private:
ptr_type _ptr;
};
inline std::ostream& operator<<(std::ostream& os, const demangled_string& str)
{
return str.write(os);
}
inline std::string operator+ (std::string l, const demangled_string& r) {
return l + r.c_str();
}
inline std::string operator+(const demangled_string& l, const std::string& r)
{
return std::string(l) + r;
}
demangled_string demangle(const char* name);
demangled_string demangle(const std::type_info& type);
demangled_string demangle(std::type_index type);
template<class T>
demangled_string demangle(T* p) {
return demangle(typeid(*p));
}
template<class T>
demangled_string demangle()
{
return demangle(typeid(T));
}
// implementation
demangled_string::demangled_string(ptr_type&& ptr) noexcept
: _ptr(std::move(ptr))
{}
std::ostream& demangled_string::write(std::ostream& os) const
{
if (_ptr) {
return os << _ptr.get();
}
else {
return os << "{nullptr}";
}
}
const char* demangled_string::c_str() const
{
if (!_ptr)
{
throw std::logic_error("demangled_string - zombie object");
}
else {
return _ptr.get();
}
}
demangled_string::operator std::string() const {
return std::string(c_str());
}
demangled_string demangle(const char* name)
{
using namespace std::string_literals;
int status = -4;
demangled_string::ptr_type ptr {
abi::__cxa_demangle(name, nullptr, nullptr, &status),
std::free
};
if (status == 0) return { std::move(ptr) };
switch(status)
{
case -1: throw std::bad_alloc();
case -2: {
std::string msg = "invalid mangled name~";
msg += name;
auto p = (char*)std::malloc(msg.length() + 1);
strcpy(p, msg.c_str());
return demangled_string::ptr_type { p, std::free };
}
case -3:
assert(!"invalid argument sent to __cxa_demangle");
throw std::logic_error("invalid argument sent to __cxa_demangle");
default:
assert(!"PANIC! unexpected return value");
throw std::logic_error("PANIC! unexpected return value");
}
}
demangled_string demangle(const std::type_info& type)
{
return demangle(type.name());
}
demangled_string demangle(std::type_index type)
{
return demangle(type.name());
}
std::string method(const demangled_string& cls, const char* method)
{
return std::string(cls) + "::" + method;
}
// test
class test_class
{
using this_class = test_class;
static auto classname() { return demangle<this_class>(); }
public:
static void test1() {
std::cout << method(demangle<this_class>(), __func__) << std::endl;
std::cout << method(classname(), __func__) << std::endl;
}
void test2() {
std::cout << method(demangle(this), __func__) << std::endl;
std::cout << method(classname(), __func__) << std::endl;
}
};
int main()
{
test_class t;
t.test1();
t.test2();
}
expected output:
test_class::test1
test_class::test1
test_class::test2
test_class::test2
The typeid operator may also be applied to a type, not just an expression: typeid(GoodClass) ought to work when you cannot access this.
Edit: without an instance you need to turn to static polymorphism. You could have a mix in base class Identifiable<X> which has a static method with the code you suggested above, but using typeid(X) instead. Your classes need to extend this class passing themselves as the template parameter (the curiously recursive template pattern), but it is not possible to ensure that a class does so:
class C : public Identifiable<C> {}; // method returns C
class D : public Identifiable<C> {}; // also returns C
Is it possible to automatically wrap a value in a temporary whose lifetime extends across the entire statement?
Originally I hoped a solution or alternative to my problem would present itself while writing the details for the question, unfortunately that didn't happen, so...
I have an abstract base class Logger that provides a streaming-like interface for generating log statements. Given an instance logger of this class, I want the following to be possible:
logger << "Option " << variable << " is " << 42;
Unlike regular streams, which simply generate a string from all the components (4 components in the example above), I want to generate an instance of a class Statement that manages a linked list of all the statement's components. The entire statement is then passed via pure virtual method to a class derived from Logger, which can iterate over all the components of the statement and do whatever with them, including obtaining information about their type, retrieving their value, or converting them to a string.
The tricky bit: I want to do the above without dynamic memory allocations. This means that every component of the statement must be wrapped by a temporary type that links the components into a traversable list, within the scope of the statement!
I posted a working example on ideone, with one problem: every component needs to be wrapped by a function call in order to generate an instance of the temporary type. The log statement therefore ends up looking like this:
logger << wrap("Option ") << wrap(variable) << wrap(" is ") << wrap(42);
All my attempts to get rid of the wrap function (e.g., using an implicit converting constructor for the component), have failed thus far, therefore this question.
How can the components of the log statement automatically be wrapped in their component type (e.g., using a converting constructor for the component), without the need for an explicit call to a wrapping function?
Alternatively, I would appreciate suggestions for other ways that achieve the same effect, i.e., allowing iteration over the components of the log statement in a class derived from logger, without dynamic memory allocations.
Reference: Full code on ideone:
#include <iostream>
#include <sstream>
struct Statement;
struct Logger;
struct ComponentBase;
//------------------------------------------------------------------------------
struct ComponentBase {
mutable ComponentBase *next;
ComponentBase() : next(nullptr) { }
virtual std::string toString() = 0;
};
template <typename T>
struct Component : ComponentBase {
T value;
Component(T value) : value(value) { }
~Component() { }
virtual std::string toString() {
std::stringstream ss;
ss << value;
return ss.str();
}
};
struct ComponentIterator {
ComponentBase *ptr;
ComponentIterator(ComponentBase *ptr) : ptr(ptr) { }
ComponentBase &operator*() { return *ptr; }
void operator++() { ptr = ptr->next; }
bool operator!=(ComponentIterator &other) { return (ptr != other.ptr); }
};
//------------------------------------------------------------------------------
struct Statement {
Logger *logger;
ComponentBase *front;
ComponentBase *back;
ComponentIterator begin() { return front; }
ComponentIterator end() { return nullptr; }
template <typename T>
Statement(Logger &logger, Component<T> &component)
: logger(&logger), front(&component), back(&component) { }
~Statement();
template <typename T>
Statement &operator<<(Component<T> &&component) {
back->next = &component;
back = &component;
return *this;
}
};
//------------------------------------------------------------------------------
struct Logger {
template <typename T>
Statement operator<<(Component<T> &&component) {
return {*this, component};
}
virtual void log(Statement &statement) = 0;
};
Statement::~Statement() {
logger->log(*this);
}
//------------------------------------------------------------------------------
template <typename T>
Component<T const &> wrap(T const &value) {
return value;
}
template <size_t N>
Component<char const *> wrap(char const (&value)[N]) {
return value;
}
//------------------------------------------------------------------------------
struct MyLogger : public Logger {
virtual void log(Statement &statement) override {
for(auto &&component : statement) {
std::cout << component.toString();
}
std::cout << std::endl;
}
};
int main() {
std::string variable = "string";
MyLogger logger;
logger << wrap("Option ") << wrap(variable) << wrap(" is ") << wrap(42);
}
I have some crazy but working solution.
Having component implemented like this you will get rid of templates all over your code:
struct Component
{
mutable Component *next;
typedef std::function<std::string()> ToStringFunction;
ToStringFunction toString; // <-- 1
template<typename T>
Component(const T& value)
: next(nullptr),
toString(nullptr)
{
toString = [&value](){
std::stringstream ss;
ss << value;
return ss.str();
};
}
};
Where (1) is the unction that knows what to do. This member std::function is a space for optimization.
And the rest of the code should look like:
struct ComponentIterator {
Component *ptr;
ComponentIterator(Component *ptr) : ptr(ptr) { }
Component &operator*() { return *ptr; }
void operator++() { ptr = ptr->next; }
bool operator!=(ComponentIterator &other) { return (ptr != other.ptr); }
};
//------------------------------------------------------------------------------
struct Statement {
Logger *logger;
Component *front;
Component *back;
ComponentIterator begin() { return front; }
ComponentIterator end() { return nullptr; }
Statement(Logger &logger, Component &component)
: logger(&logger), front(&component), back(&component) { }
~Statement();
Statement &operator<<(Component &&component) {
back->next = &component;
back = &component;
return *this;
}
};
//------------------------------------------------------------------------------
struct Logger {
Statement operator<<(Component &&component) {
return{ *this, component };
}
virtual void log(Statement &statement) = 0;
};
Statement::~Statement() {
logger->log(*this);
}
//------------------------------------------------------------------------------
struct MyLogger : public Logger {
virtual void log(Statement &statement) override {
for (auto &&component : statement) {
std::cout << component.toString();
}
std::cout << std::endl;
}
};
int main() {
std::string variable = "string";
MyLogger logger;
//logger << wrap("Option ") << wrap(variable) << wrap(" is ") << wrap(42);
logger << 42;
logger << variable << " is " << 42;
logger << "Option " << variable << " is " << 42;
}
this will print:
42
string is 42
Option string is 42
UPD
as dyp advised here is alternative implementation of the Component structure without lambda:
struct Component
{
mutable Component *next;
void* value;
std::string toString(){
return _toString(this);
}
template<typename T>
Component(const T& inValue)
: next(nullptr),
value((void*)&inValue),
_toString(toStringHelper<T>)
{}
private:
typedef std::string(*ToStringFunction)(Component*);
ToStringFunction _toString;
template<typename T>
static std::string toStringHelper(Component* component)
{
const T& value = *(T*)component->value;
std::stringstream ss;
ss << value;
return ss.str();
}
};
I propose a solution tuple based:
template <class... Ts> class streamTuple;
struct Logger {
template <typename T>
streamTuple<T> operator<<(const T& t);
template <typename Tuple, std::size_t ... Is>
void dispatch(const Tuple& tup, std::index_sequence<Is...>)
{
int dummy[] = {0, (void(std::cout << std::get<Is>(tup) << " "), 0)...};
static_cast<void>(dummy); // Avoid unused variable warning
}
// Logger can take generic functor to have specific dispatch
// Or you may reuse your virtual method taking ComponentBase.
};
template <class... Ts> class streamTuple
{
public:
streamTuple(Logger* logger, const std::tuple<Ts...>& tup) :
logger(logger), tup(tup) {}
streamTuple(streamTuple&& rhs) : logger(rhs.logger), tup(std::move(rhs.tup))
{
rhs.logger = nullptr;
}
~streamTuple()
{
if (logger) {
logger->dispatch(tup, std::index_sequence_for<Ts...>());
}
}
template <typename T>
streamTuple<Ts..., const T&> operator << (const T& t) &&
{
auto* moveddLogger = logger;
logger = nullptr;
return {moveddLogger, std::tuple_cat(tup, std::tie(t))};
}
private:
Logger* logger;
std::tuple<Ts...> tup;
};
template <typename T>
streamTuple<T> Logger::operator<<(const T& t) {
return {this, t};
}
Demo
And usage:
int main() {
Logger log;
std::string variable = "string";
log << variable << 42 << "hello\n";
}
I'm making a simple logging class with a pointer to either a std::ofstream or std::cerr.
Is there any simple way to use a smart pointer for auto clean-up regardless of which stream is used?
The code must compile on clang++, g++, and VS2013.
Code
#include <iostream>
#include <fstream>
#include <string>
class Logger {
private:
std::ostream * output_stream{ nullptr };
bool using_file{ false };
public:
Logger()
{
output_stream = &std::cerr;
using_file = false;
}
Logger(std::string file)
{
output_stream = new std::ofstream(file);
using_file = true;
}
~Logger()
{
if (using_file)
{
delete output_stream;
}
}
template<typename T>
void log(T info)
{
*output_stream << info << std::endl;
}
};
class tmp {
int i{ 4 };
friend std::ostream & operator<<(std::ostream &os, const tmp& p);
};
std::ostream &operator<<(std::ostream &os, const tmp& p)
{
return os << p.i;
}
int main()
{
tmp t;
Logger logger;
logger.log(t);
system("pause");
return 0;
}
Attempts
std::unique_ptr
I can use std::unique_ptr for the file like so:
std::unique_ptr<std::ostream> p;
p = std::make_unique<std::ofstream>("file.txt");
*p << "hi there" << std::endl;
Trying this with std::cout warns me about a deleted function (assuming that's the constructor.
std::unique_ptr<std::ostream> p2;
p2 = std::make_unique<std::ostream>(std::cout);
*p2 << "hey" << std::endl;
std::shared_ptr
Because std::unique_ptr is only for owning things, and std::cout shouldn't be owned, I thought I'd try std::shared_ptr
std::shared_ptr<std::ostream> p;
p = std::make_shared<std::ostream>(std::cout);
*p << "hola" << std::endl;
It gives me the same deleted constructor error. p = &std::cout complains about a type mismatch, so it's also not working.
You can use a shared_ptr with a deleter that does not delete anything in the case of cerr and just a normally constructed shared_ptr in the case of ofstream
class Logger {
private:
std::shared_ptr<std::ostream> output_stream{ nullptr };
public:
Logger() :
output_stream(&std::cerr, [](std::ostream*){})
{ }
Logger(std::string file) :
output_stream(std::make_shared<std::ofstream>(file))
{ }
// default destructor is OK
template<typename T>
void log(T info)
{
*output_stream << info << std::endl;
}
};
I would just have two pointers, one smart and one raw.
The raw pointer is always used to refer to the stream. The smart pointer is just used for clean-up if needed.
class Logger {
private:
std::unique_ptr<std::ofstream> file_stream;
std:ostream *stream;
public:
Logger() : stream(&std::cerr) {}
Logger(const std::string& file)
: file_stream(std::make_unique<std::ofstream>(file)), stream(file_stream.get()){}
template<typename T>
void log(T info) {
*stream << info << std::endl;
}
};
I tend to try to avoid cases where I want an object to "own" such things. In the times I did not have much choice, I ended up settling with a "shouldDelete" flag or a callback.
class Logger {
public:
Logger(std::ofstream *outputStream, bool deleteOutputStream)
: outputStream(outputStream), deleteOutputStream(deleteOutputStream)
{ }
~Logger()
{
if (deleteOutputStream) delete outputStream;
}
};
Logger logger(&std::cout, false);
class Logger {
public:
typedef std::function<void(std::ostream*)> Deleter;
typedef std::unique_ptr<std::ostream, Deleter> OStreamPointer;
Logger(OStreamPointer &&outputStream)
: outputStream(std::move(outputStream))
{ }
~Logger() { }
private:
OStreamPointer outputStream;
};
Logger logger(Logger::OStreamPointer(
&std::cout,
[](std::ostream*) {})); //no-op callback
You could do this by releasing the smart pointer in the destructor (and elsewhere) in the cases where it shouldn't be deleted, but that's not worth the hassle IMO.
Instead, I'd recommend simply using two pointers: one for streams that need to be managed and one for those that don't:
class Logger {
private:
std::ostream * unmanaged_stream{ nullptr };
std::unique_ptr<std::ostream> managed_stream{ nullptr };
bool using_file{ false };
std::ostream& output_stream()
{
return using_file ? *managed_stream : *unmanaged_stream;
}
public:
Logger()
: unmanaged_stream{&std::cerr},
using_file{false}
{
}
Logger(const std::string& file)
: managed_stream{std::make_unique<std::ofstream>(file)},
using_file{true}
{
}
template<typename T>
void log(T info)
{
output_stream() << info << std::endl;
}
};
If saving space is a priority you could put them in a union, but then you'd have to explicitly call the destructor and placement new to define the active member, which again is more hassle and probably not worth it.
I have the following code with a custom Variant class and a custom SmartPtr class:
using namespace std;
class Object
{
public:
};
template<typename T>
class SmartPtr
{
public:
template<typename Y>
explicit SmartPtr(Y* p) { p_ = p; }
SmartPtr(std::nullptr_t) { p_ = nullptr; }
private:
T* p_;
};
class Variant
{
public:
Variant(bool b) : _b(b) { }
private:
bool _b;
};
class Obj
{
public:
void test(SmartPtr<Object> /*p*/) { cout << "smartptr version!" << endl; }
void test(Variant /*v*/) { cout << "variant version!" << endl; }
};
int main(int argc, const char *argv[])
{
Obj o;
o.test(nullptr); // calls SmartPtr version
o.test(true); // calls Variant version
o.test(false); // -> compiler error: ambiguous call to overloaded function
return 0;
}
I assume that the boolean false can be converted both to the Variant and to 0 then to nullptr and then to SmartPtr, which causes this error.
Any chances of avoiding this conversion?
For the user of the library an API which works with 'o.test(true);' but requires something like 'o.test(Variant(false));' to compile is not very intuitive.
I believe I have an ideal solution. It only requires that the test function be altered, so it leaves SmartPtr and Variant alone, which is ideal. It adds a non-defined templated overload to test that has specializations for bool and nullptr that are defined. This directly dispatches bool and nullptr to the desired specialization, but causes link errors on other unhandled types. I'm so glad to have this worked out because I've certainly run into this in many forms myself. I wish you could use explicit of function parameters!!
I got the idea from here: C++ templates that accept only certain types
using namespace std;
class Object
{
public:
};
class Variant
{
public:
Variant( bool b) : _b(b) { }
private:
bool _b;
};
template<typename T>
class SmartPtr
{
public:
SmartPtr(std::nullptr_t null) { p_ = nullptr; }
template<typename Y>
SmartPtr(Y* p) { p_ = p; }
private:
T* p_;
};
class Obj
{
public:
void test(SmartPtr<Object> here /*p*/) {
cout << "smartptr version!" << endl;
}
void test(Variant /*v*/) { cout << "variant version!" << endl; }
template<typename T> void test(T t);
template<>
void test<bool>(bool b) {
cout << "bool specialization" << endl;
test(Variant(b));
}
template<>
void test<std::nullptr_t>(std::nullptr_t null) {
cout << "nullptr specialization" << endl;
test(SmartPtr<Object>(nullptr));
}
};
int main(int argc, const char *argv[])
{
Obj o;
Obj c;
Object object;
//o.test(3); // Gives link error LNK2019
o.test(Variant(true)); // calls Variant version
o.test(SmartPtr<Object>(&object)); // calls SmartPtr version
o.test(nullptr); // dispatched to SmartPtr version by nullptr specialization
o.test(true); // dispatched to Variant version by bool specialization
o.test(false); // dispatched to Variant version by bool specialization
return 0;
}
I had already answered with something not ideal, so I leave that answer in tact as what follows:
=============================================
I don't have an ideal solution here, and I don't know the constraints you have on your code so this may not be of functional use to you, but the following is sensible. It disallows code to use nullptr at compile time and relies on a global null_smart constant to be used in all cases where the caller is simply showing no interest in passing an object.
#include <iostream>
using namespace std;
class Object
{
public:
};
class Variant
{
public:
Variant(bool b) : _b(b) { }
private:
Variant(std::nullptr_t) {};
private:
bool _b;
};
template<typename T>
class SmartPtr
{
public:
SmartPtr() { p_ = nullptr; }
template<typename Y>
SmartPtr(Y* p) { p_ = p; }
private:
T* p_;
};
class Obj
{
public:
void test(SmartPtr<Object> /*p*/) { cout << "smartptr version!" << endl; }
void test(Variant /*v*/) { cout << "variant version!" << endl; }
};
const SmartPtr<Object> null_smart;
int main(int argc, const char *argv[])
{
Obj o;
o.test(null_smart); // calls SmartPtr version, without interest in passing object
o.test(true); // calls Variant version
o.test(false); // calls Variant version
return 0;
}
It's cleaner than the true/Variant(false) issue, but still a bit on the picky side.