Click here to Skip to main content
15,393,863 members

Comments by PaltryProgrammer (Top 25 by date)

   
If it is standard how then can it not be accepted.
   
Is your "user" the application writer i.e. the caller of my library? My "user" is the customer who purchases the application written by the application writer who utilizes my library. This final user's use of the application is unpredictable with infinite possible scenarios.

As for severity of error I do not see it of importance. Errors occur. Presumably they must be reported. What difference the means of doing so. I do not understand why debugging is required merely because an error is reported via exception. If the exact same error were reported via let's say a function return of an error code would debugging not be required? As for debugging I examined the article you kindly provided as near as I can discern the stack trace only provides a list of called functions. I do not see this as very useful. Further in my exception classes I intend to provide the throw'ing function signature and its' arguments as these may be helpful to caller. As for the bulk of the article it is a bit over my head as I do not wish to deal with threads or signals though perhaps I should or leave it to the caller of my library to worry of such things.

Why would if statements and errno be required if the code is found to be correct and free of bugs for a "scenario".
   
"... for the scenario being executed."?
How does an application writer know what scenarios his/her users will execute?

"... returning nullptr for example, that is preferable."?
To quote Mr. Stroustrup "What good can using exceptions do for me? The basic answer is: Using exceptions for error handling makes you code simpler, cleaner, and less likely to miss errors. But what's wrong with "good old errno and if-statements"? The basic answer is: Using those, your error handling and your normal code are closely intertwined. That way, your code gets messy and it becomes hard to ensure that you have dealt with all errors (think "spaghetti code" or a "rat's nest of tests")."

Of course returning npos or cend() from find makes sense. It is not an error to learn something is not present in a range.
PaltryProgrammer 6-Aug-22 14:59pm View
   
File I/O Do you wish more details?
PaltryProgrammer 6-Aug-22 14:59pm View
   
"...impossible to recover."? That is not my understanding of the recommendation of one Mr. Stroustrup per https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#e2-throw-an-exception-to-signal-that-a-function-cant-perform-its-assigned-task .

How can one speak of correct code w/o proof of same.

Perhaps the user of my library wishes to be resilient. I assume I should not assume one or the other.
PaltryProgrammer 6-Aug-22 12:25pm View
   
I have difficulty understanding the first statement as it is my understanding it is impossible to determine code is 100% correct w/o error and free of defect so catching exceptions seems a necessity perhaps that is why they ae provided in C++. As for the latter statement I am also again confused as the need to throw exceptions has little to do as near as I can discern w/ the possibility of using the library correctly as doing so can not be guaranteed or assumed.
PaltryProgrammer 6-Aug-22 12:08pm View
   
Of course if the user makes no errors then no exceptions will be thrown or need be caught but of course this can not be relied on.
PaltryProgrammer 6-Aug-22 11:46am View
   
The library throws what I believe logically needs to be thrown. However "too many" is a matter of programming convenience not logic. The two are unrelated or so I believe unless a technical means exists to prevent the caller to the library from needing to write a long list of catch's in order to disambiguate each one. May I please inquire in your long experience have you written a library and if so were multiple exceptions required and if so how were they organized. As for the function of the library I do not see why that is important. Thank You Kindly
PaltryProgrammer 16-May-22 21:28pm View
   
The template "requires" statement needs to be in the definition as well as the declaration of "bar" else it will not compile which it would succeed in doing if it did not reference "cfoo::result_type" e.g. if the "requires" clause for "bar" was instead "requires is_integral_v". Yes a name would be needed for the "bar" "U" parameter for useful execution of course but all I wish to learn is how to obtain successful compilation. - Best
PaltryProgrammer 5-Apr-22 3:30am View
   
Thank You
PaltryProgrammer 19-Dec-21 23:29pm View
   
I just noticed your post is a few months old but in case you are still interested the site below may or may not be useful All I know is it refers to expression templates It is a boost library page
https://www.boost.org/doc/libs/1_78_0/doc/html/yap.html
PaltryProgrammer 16-Dec-21 21:58pm View
   
Thank You for your Kind interest Yes I have confirmed if i is declared const the expected foobar is called i.e. the first However I still do not understand why the same is not called even if i is not const - Kind Regards - Cheerio
PaltryProgrammer 10-Dec-21 23:30pm View
   
Yes Thanks I would have bet my life I tried the external re-declare as stated in my post Several times in fact All I did was reboot Visual Studio and follow your lead and Bingo Presto it works now - Thanks again - Cheerio
PaltryProgrammer 14-Nov-21 6:55am View
   
As near as I understand the solution being proposed here is for each header file to include the header files needed so the source file need only include its' own header and Voila the problem is solved I have been avoiding this method for philosophical reasons and only include'ing into source but of course will attempt it now Thank You Kindly
PaltryProgrammer 1-Oct-21 15:46pm View
   
Thank you for your reply I am surprised those who tout its speed benefits do not mention this restriction I can only conclude modules are of little use for faster builds as templates are common just as in the Standard Template Library So why does std.core exist? How is it an improvement over #includes<...>? Thank you again - Cheerio
PaltryProgrammer 14-Aug-21 5:16am View
   
By "modules" I mean The new C++ feature as per https://eel.is/c%2B%2Bdraft/module As for their relation to circular dependency I do not know I was hoping for some module magic Unless I can avoid circular dependency in my code my solution will be

#include <memory>
#include <iostream>
using namespace std;

#define FUNCSIG cout << __FUNCSIG__ << endl;

class A;
class B;
class A
{
private:
unique_ptr b;
public:
A();
void set_B(unique_ptr&& _b);
void do_something_with_B();
void foobar_A();
};

class B
{
private:
unique_ptr a;
public:
B();
void set_A(unique_ptr
&& _a);
void do_something_with_A();
void foobar_B();
};

A::A() : b(nullptr) { FUNCSIG }
void A::set_B(unique_ptr&& _b) { b = move(_b); }
void A::do_something_with_B() { FUNCSIG b->foobar_B(); }
void A::foobar_A() { FUNCSIG }

B::B() : a(nullptr) { FUNCSIG }
void B::set_A(unique_ptr
&& _a) { a = move(_a); }
void B::do_something_with_A() { FUNCSIG a->foobar_A(); }
void B::foobar_B() { FUNCSIG }

int main()
{
cout << "Hello World\n";
A a;
a.set_B(make_unique());
B b;
b.set_A(make_unique
());
a.do_something_with_B();
b.do_something_with_A();
}
PaltryProgrammer 14-Aug-21 4:27am View
   
Thank You I am reasonably familiar w/ templates I utilize them almost universally for my classes and functions Circular dependency is a problem I have yet to solve I was hoping modules would do so for me The only method I know of to compile w/ circular dependency is to present forward references utilizing pointers or references to member classes and implementation details for each header file following all the forward references I will however attempt to heed your advice and attempt to redesign my code to avoid the problem in the first place Thank You Kindly - Cheerio
PaltryProgrammer 7-Aug-20 3:57am View
   
Deleted
Yes the result will be "something" but it will not be the korekt sum thing as I explained. I decided upon another solution however. That is to initialize the sum to the first value of the interval stored in the vector and proceed with the summing loop starting with the second element of the vector. I avoided this method as it prevents utilizing the range-based for loop which I prefer so now I have to perform the loop the old fashioned way either with an index or an iterator. Thank you for your kind concern. I hope I haven't wasted your time with my paltry thoughts. Best Wishes Cheerios

If you wish to examine the class here it is in all its glory.

template<typename numericType>
MAKERCLASS(cinterval)
{
public:
	using numeric_type = numericType;
	using this_type = cinterval<numeric_type>;
	FRIENDINSERTION(cinterval)
	using interval_type = this_type;
	numeric_type low, high;

	cinterval(numeric_type _low, numeric_type _high) : low(_low), high(_high) { ASSERTINVARIANT(DATANAMEVALUEA(_low), DATANAMEVALUEA(_high)); }
	numeric_type begin() const { return low; }
	numeric_type end()   const { return high +1; }
	numeric_type width() const { return high +1 - low; }
	bool operator <  (const interval_type& rhs) const { return high < rhs.low; }
	bool operator >  (const interval_type& rhs) const { return rhs.high < low; }
	bool operator == (const interval_type& rhs) const { return low == rhs.low && high == rhs.high; }
	bool operator != (const interval_type& rhs) const { return !operator == (rhs); }
	this_type& operator += (const interval_type& rhs)
	{
		assert(contiguous(*this, rhs));
		if (*this < rhs) high = rhs.high;
		else low = rhs.low;
		return *this;
	}
	void shift_right(numeric_type d) { low += d; high += d; }
	void shift_left(numeric_type d) { low -= d; high -= d; }
	bool assert_invariant() const { return low <= high; }
	TOBASICOSTREAMSIGNATURE
	{
		TOBASICOSTREAMPREAMBLE
		auto lbracket = get_left_bracket<char_type>();
		auto rbracket = get_right_bracket<char_type>();
		auto lparen = get_left_paren<char_type>();
		auto rparen = get_right_paren<char_type>();
		DELIMITERCOLOR << lbracket;
		INTERVALCOLOR << XFormatNumber<char_type>(low);
		CONSOLEDEFAULTCOLOR(bos) << space;
		INTERVALCOLOR << XFormatNumber<char_type>(high);
		DELIMITERCOLOR << rbracket;
		DELIMITERCOLOR << lparen;
		INTERVALCOLOR << XFormatNumber<char_type>(width());
		DELIMITERCOLOR << rparen;
		CONSOLEDEFAULTCOLOR(bos);
	}

	static bool overlap(const interval_type& lhs, const interval_type& rhs) { return lhs.low <= rhs.high && rhs.low <= lhs.high; }
	static bool overlap(numeric_type lhs, const interval_type& rhs) { return lhs >= rhs.low  && lhs <= rhs.high; }
	static bool contiguous(const interval_type& lhs, const interval_type& rhs)
	{ return lhs.high + 1 == rhs.low || rhs.high + 1 == lhs.low; }

	//      ---lhs---
	//      |       |
	//   -------    |		[1]	case
	//   ------------		[2]
	//   ---------------	[3]
	//      ---     |		[4]
	//      ---------		[5]
	//      ------------	[6]
	//      |  ---  |		[7]
	//      |  ------		[8]
	//      |  ---------	[9]

	enum overlap_case_etype {
		overlap_case_1 = 1, overlap_case_2, overlap_case_3,
		overlap_case_4,     overlap_case_5, overlap_case_6,
		overlap_case_7,     overlap_case_8, overlap_case_9 };

	static overlap_case_etype OVERLAPCASE(const interval_type& lhs, const interval_type& rhs)
	{
		overlap_case_etype overlap_case = [&]() {
			if(lhs.low < rhs.low) // [7] [8] [9]
			{
				if(lhs.high < rhs.high) // [9]
					return interval_type::overlap_case_9;
				else if(lhs.high == rhs.high) // [8]
					return overlap_case_8;
				else // [7]
					return overlap_case_7;
			}
			else if(lhs.low == rhs.low) /
PaltryProgrammer 7-Aug-20 3:53am View
   
Deleted
Yes the result will be "something" but it will not be the korekt sum thing as I explained. I decided upon another solution however. That is to initialize the sum to the first value of the interval stored in the vector and proceed with the summing loop starting with the second element of the vector. I avoided this method as it prevents utilizing the range-based for loop which I prefer so now I have to perform the loop the old fashioned way either with an index or an iterator. Thank you for your kind concern. I hope I haven't wasted your time with my paltry thoughts. Best Wishes Cheerios

If you wish to examine the class here it is in all its glory.
template<typename numericType>
MAKERCLASS(cinterval)
{
public:
	using numeric_type = numericType;
	using this_type = cinterval<numeric_type>;
	FRIENDINSERTION(cinterval)
	using interval_type = this_type;
	numeric_type low, high;

	cinterval(numeric_type _low, numeric_type _high) : low(_low), high(_high) { ASSERTINVARIANT(DATANAMEVALUEA(_low), DATANAMEVALUEA(_high)); }
	numeric_type begin() const { return low; }
	numeric_type end()   const { return high +1; }
	numeric_type width() const { return high +1 - low; }
	bool operator <  (const interval_type& rhs) const { return high < rhs.low; }
	bool operator >  (const interval_type& rhs) const { return rhs.high < low; }
	bool operator == (const interval_type& rhs) const { return low == rhs.low && high == rhs.high; }
	bool operator != (const interval_type& rhs) const { return !operator == (rhs); }
	this_type& operator += (const interval_type& rhs)
	{
		assert(contiguous(*this, rhs));
		if (*this < rhs) high = rhs.high;
		else low = rhs.low;
		return *this;
	}
	void shift_right(numeric_type d) { low += d; high += d; }
	void shift_left(numeric_type d) { low -= d; high -= d; }
	bool assert_invariant() const { return low <= high; }
	TOBASICOSTREAMSIGNATURE
	{
		TOBASICOSTREAMPREAMBLE
		auto lbracket = get_left_bracket<char_type>();
		auto rbracket = get_right_bracket<char_type>();
		auto lparen = get_left_paren<char_type>();
		auto rparen = get_right_paren<char_type>();
		DELIMITERCOLOR << lbracket;
		INTERVALCOLOR << XFormatNumber<char_type>(low);
		CONSOLEDEFAULTCOLOR(bos) << space;
		INTERVALCOLOR << XFormatNumber<char_type>(high);
		DELIMITERCOLOR << rbracket;
		DELIMITERCOLOR << lparen;
		INTERVALCOLOR << XFormatNumber<char_type>(width());
		DELIMITERCOLOR << rparen;
		CONSOLEDEFAULTCOLOR(bos);
	}

	static bool overlap(const interval_type& lhs, const interval_type& rhs) { return lhs.low <= rhs.high && rhs.low <= lhs.high; }
	static bool overlap(numeric_type lhs, const interval_type& rhs) { return lhs >= rhs.low  && lhs <= rhs.high; }
	static bool contiguous(const interval_type& lhs, const interval_type& rhs)
	{ return lhs.high + 1 == rhs.low || rhs.high + 1 == lhs.low; }

	//      ---lhs---
	//      |       |
	//   -------    |		[1]	case
	//   ------------		[2]
	//   ---------------	[3]
	//      ---     |		[4]
	//      ---------		[5]
	//      ------------	[6]
	//      |  ---  |		[7]
	//      |  ------		[8]
	//      |  ---------	[9]

	enum overlap_case_etype {
		overlap_case_1 = 1, overlap_case_2, overlap_case_3,
		overlap_case_4,     overlap_case_5, overlap_case_6,
		overlap_case_7,     overlap_case_8, overlap_case_9 };

	static overlap_case_etype OVERLAPCASE(const interval_type& lhs, const interval_type& rhs)
	{
		overlap_case_etype overlap_case = [&]() {
			if(lhs.low < rhs.low) // [7] [8] [9]
			{
				if(lhs.high < rhs.high) // [9]
					return interval_type::overlap_case_9;
				else if(lhs.high == rhs.high) // [8]
					return overlap_case_8;
				else // [7]
					return overlap_case_7;
			}
			else if(lhs.low == rhs.low) //
PaltryProgrammer 6-Aug-20 17:08pm View
   
By "sum" I mean to overload operator += on this object type i.e. class cinterval as described above. If you wish you can think of "sum" as any binary operator defined for a type in this case class cinterval. However there is no identity value if that is the correct term which I know of for this class which permits an initialization of a sum as it otherwise would be for simple arithmetic of zero and therein lies the crux of my problem which is why the current version relies on std::optional<cinterval> sum; as the initial value. Thank you kindly Cheerios
PaltryProgrammer 6-Aug-20 16:23pm View
   
The "zero" value is never in the vector. In normal arithmetic addition the initial value of a sum would of course be 0 (zero) but there is no "zero" value for class cinterval unless I construct such a special case but of course in programming special cases are to be avoided. Thank you kindly Cheerios
PaltryProgrammer 6-Aug-20 15:45pm View
   
Thank you for your response. The object which I am summing by overloading operator += is an interval for example class cinterval { int m_min; int_m_max; } I wish to form the sum of contiguous such intervals by which I mean constructing a new interval which is the union of the two with the required m_min and m_max values. I prefer to avoid a special value of {0, 0} as it would need to specially and separately considered in any and all cinterval operations which would lead to inelegant and error prone code. In particular to perform such a sum with an initial {0,0} sum the code can not merely assign the m_min and m_max as it otherwise would instead it would need to examine the initial sum on each addition to determine if it is of this special kind. For example if the first term in the vector was { 10, 100 } the result of naively summing it would be { 0, 100 } which would not be correct as the correct value is merely the first non-"zero" term i.e. { 10, 100 }. So I do not know how to construct a "zero" valued interval This is why I am currently utilizing std::optional Thank you kindly
PaltryProgrammer 14-May-20 14:53pm View
   
Dziękuję za odpowiedź. Może moje rozwiązanie pomoże komuś innemu. Może pan wie jak rozwiązać mój problem.
PaltryProgrammer 14-May-20 13:51pm View
   
Your comment got me to realize I should be utilizing "is a" and "has a" relationships in my design Since a node is not a particular kind of vector or map but instead "has" children the vector of child nodes should be a member class not a base class As for the map it is simply a tool to access the vector and of course is not a base form of node so it also should be a member class Thank you kindly Cheerios
PaltryProgrammer 14-May-20 4:33am View
   
I have a multiary tree Each node is a vector because it has children However when traversing the tree iteratively it is necessary to maintain a record of the pointer to the previously visited node When that node is a child of the current node it is then necessary to find the next child node in the vector in an efficient manner The map uses child node pointers as keys to provide the indices into the vector so that the next child pointer can be easily obtained Thank you for your comment Cheerios