- Ugly code to solve a combinatorial problem with an integer sum - 2 Updates
- How to portably cast from void* to int - 10 Updates
- Zeroing in the constructor - 3 Updates
- operator+ - 2 Updates
- constexpr - 5 Updates
- Question about derived class member function call - 1 Update
- Avoid 'int' and associates. - 1 Update
- How to call virtual functions in C++ - 1 Update
Paul <pepstein5@gmail.com>: Jun 16 12:12PM -0700 I tried the problem of generating solutions like 123 - 45 - 67 + 89 = 100. The point is that we get 100 and we use the digits from 1 to 9 in consecutive order. My code is really ugly, and it also took me ages to do. Any insights on how I can improve it? The problem is stated more accurately in the initial comments. Many thanks for your help. Paul /*Problem 5 Write a program that outputs all possibilities to put + or - or nothing between the numbers 1, 2, ..., 9 (in this order) such that the result is always 100. For example: 1 + 2 + 34 - 5 + 67 - 8 + 9 = 100.*/ // First a utility function that inserts + and - into a vector of numbers to get a result int insertSigns (const std::vector<int>& numbers, const std::string& plusesAndMinuses) { if(numbers.empty()) return 0; int result = numbers[0]; for(int i = 1; i < numbers.size(); ++i) result += (plusesAndMinuses[i - 1] == '+' ? numbers[i] : -numbers[i]); return result; } // Generate all combinations of plus/minus signs of a given length. Use recursion std::vector<std::string> plusesAndMinuses(int n) { std::vector<std::string> results; if(!n) return results; if(n == 1) return {"+", "-"}; const std::vector<std::string> formerResults = plusesAndMinuses(n-1); for(int i = 0; i < formerResults.size(); ++i) { results.push_back("+" + formerResults[i]); results.push_back("-" + formerResults[i]); } return results; } // Generate all vectors of numbers that can arise from concatenations in a list of numbers // Numbers can only be concatenated with their neighbours. Use recursion std::vector<std::vector<int>> concatenation (const std::vector<int>& numbers, int base = 10) { if(numbers.size() <= 1) return {numbers}; const std::vector<int> tail(++numbers.begin(), numbers.end()); const std::vector<std::vector<int>> concatenateTail = concatenation(tail, base); std::vector<std::vector<int> > results; for(int i = 0; i < concatenateTail.size(); ++i) { std::vector<int> newVec; newVec.push_back(concatenate(numbers[0], concatenateTail[i][0])); for(int j = 1; j < concatenateTail[i].size(); ++j) newVec.push_back(concatenateTail[i][j]); results.push_back(newVec); newVec.clear(); newVec.push_back(numbers[0]); for(int j = 0; j < concatenateTail[i].size(); ++j) newVec.push_back(concatenateTail[i][j]); results.push_back(newVec); } return results; } // Investigates whether a number can be obtained from concatenation of a given vector // Keeps track of all +, - sequences and concatenations which work. void findSequences (int numberObtained, const std::vector<int>& numbers, std::vector<std::string>& plusMinus, std::vector<std::vector<int>>& sequences, int base = 10) { plusMinus.clear(); sequences.clear(); auto collection = concatenation(numbers, base); for(const auto& vec : collection) { const auto& signs = plusesAndMinuses(vec.size() - 1); for(auto& str : signs) if(insertSigns(vec, str) == numberObtained) { plusMinus.push_back(str); sequences.push_back(vec); } } } // Display the above result void display(int numberObtained, const std::vector<std::string>& plusMinus, const std::vector<std::vector<int>>& sequences) { if(plusMinus.empty()) std::cout << std::endl << numberObtained << " can not be obtained. "; for(int i = 0; i < plusMinus.size(); ++i) { std::cout << std::endl; std::cout << sequences[i][0]; for(int j = 0; j < plusMinus[i].length(); ++j) std::cout << " " << plusMinus[i][j] << " " << sequences[i][j + 1]; std::cout << " = " << numberObtained << std::endl; } } // Combining above steps to calculate and then display results. void display(int numberObtained, const std::vector<int>& numbers, int base = 10) { std::vector<std::string> plusMinus; std::vector<std::vector<int> > results; findSequences(numberObtained, numbers, plusMinus, results, base); display(numberObtained, plusMinus, results); } // Test with given input. void testProblem5() { std::vector<int> testVec; for(int i = 1; i < 10; ++i) testVec.push_back(i); const int numberObtained = 100; display(numberObtained, testVec); } |
Paul <pepstein5@gmail.com>: Jun 16 12:20PM -0700 On Tuesday, June 16, 2015 at 8:12:30 PM UTC+1, Paul wrote: > My code is really ugly, and it also took me ages to do. Any insights on how I can improve it? The problem is stated more accurately in the initial comments. > Many thanks for your help. > Paul Sorry, I left off the concatenate function. There's also a bug so that, contrary to what I claim, it won't work with bases other than 10. I'll repost the whole thing, fixing that bug. // Concatenating numbers int concatenate(int x, int y, int base = 10) { for(int i = 0; i < numDigits(y, base); ++i) x *= base; return x + y; } /*Problem 5 Write a program that outputs all possibilities to put + or - or nothing between the numbers 1, 2, ..., 9 (in this order) such that the result is always 100. For example: 1 + 2 + 34 - 5 + 67 - 8 + 9 = 100.*/ // First a utility function that inserts + and - into a vector of numbers to get a result int insertSigns (const std::vector<int>& numbers, const std::string& plusesAndMinuses) { if(numbers.empty()) return 0; int result = numbers[0]; for(int i = 1; i < numbers.size(); ++i) result += (plusesAndMinuses[i - 1] == '+' ? numbers[i] : -numbers[i]); return result; } // Generate all combinations of plus/minus signs of a given length. Use recursion std::vector<std::string> plusesAndMinuses(int n) { std::vector<std::string> results; if(!n) return results; if(n == 1) return {"+", "-"}; const std::vector<std::string> formerResults = plusesAndMinuses(n-1); for(int i = 0; i < formerResults.size(); ++i) { results.push_back("+" + formerResults[i]); results.push_back("-" + formerResults[i]); } return results; } // Generate all vectors of numbers that can arise from concatenations in a list of numbers // Numbers can only be concatenated with their neighbours. Use recursion std::vector<std::vector<int>> concatenation (const std::vector<int>& numbers, int base = 10) { if(numbers.size() <= 1) return {numbers}; const std::vector<int> tail(++numbers.begin(), numbers.end()); const std::vector<std::vector<int>> concatenateTail = concatenation(tail, base); std::vector<std::vector<int> > results; for(int i = 0; i < concatenateTail.size(); ++i) { std::vector<int> newVec; newVec.push_back(concatenate(numbers[0], concatenateTail[i][0], base)); for(int j = 1; j < concatenateTail[i].size(); ++j) newVec.push_back(concatenateTail[i][j]); results.push_back(newVec); newVec.clear(); newVec.push_back(numbers[0]); for(int j = 0; j < concatenateTail[i].size(); ++j) newVec.push_back(concatenateTail[i][j]); results.push_back(newVec); } return results; } // Investigates whether a number can be obtained from concatenation of a given vector // Keeps track of all +, - sequences and concatenations which work. void findSequences (int numberObtained, const std::vector<int>& numbers, std::vector<std::string>& plusMinus, std::vector<std::vector<int>>& sequences, int base = 10) { plusMinus.clear(); sequences.clear(); auto collection = concatenation(numbers, base); for(const auto& vec : collection) { const auto& signs = plusesAndMinuses(vec.size() - 1); for(auto& str : signs) if(insertSigns(vec, str) == numberObtained) { plusMinus.push_back(str); sequences.push_back(vec); } } } // Display the above result void display(int numberObtained, const std::vector<std::string>& plusMinus, const std::vector<std::vector<int>>& sequences) { if(plusMinus.empty()) std::cout << std::endl << numberObtained << " can not be obtained. "; for(int i = 0; i < plusMinus.size(); ++i) { std::cout << std::endl; std::cout << sequences[i][0]; for(int j = 0; j < plusMinus[i].length(); ++j) std::cout << " " << plusMinus[i][j] << " " << sequences[i][j + 1]; std::cout << " = " << numberObtained << std::endl; } } // Combining above steps to calculate and then display results. void display(int numberObtained, const std::vector<int>& numbers, int base = 10) { std::vector<std::string> plusMinus; std::vector<std::vector<int> > results; findSequences(numberObtained, numbers, plusMinus, results, base); display(numberObtained, plusMinus, results); } // Test with given input. void testProblem5() { std::vector<int> testVec; for(int i = 1; i < 10; ++i) testVec.push_back(i); const int numberObtained = 100; display(numberObtained, testVec); } |
Melzzzzz <mel@zzzzz.com>: Jun 16 04:51PM +0200 Problem is this: void f(void*p){ // c callback int i = (int)p; ... } but this gives error when p is 64 bit and int 32 bit. I can cast to long but long does not have to be 64 bit,either. What do you suggest? |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 16 11:03AM -0400 On 6/16/2015 10:51 AM, Melzzzzz wrote: > but this gives error when p is 64 bit and int 32 bit. > I can cast to long but long does not have to be 64 bit,either. > What do you suggest? I suggest the type that can contain the value. The standard does not provide a type that fits, leaving it to the implementation. If 'long' is not large enough, use 'long long'. Usually you need to write some implementation-specific conditionally compiled code with typedefs producing the needed types, like #if WIN32 typedef long integraltypeforstoringpointers; #elif WIN64 typedef long long integraltypeforstoringpointers; #elif ... ... So, then you use that type to cast. But please don't use C-style casts, use 'reinterpret_cast', that's exactly what it's for. E.g.: integraltypeforstoringpointers i = reinterpret_cast<integraltypeforstoringpointers>(p); and the length of the statement and type name should be a warning that you are doing something a bit unusual, and anybody who reads the code needs to pay attention. V -- I do not respond to top-posted replies, please don't ask |
Robert Wessel <robertwessel2@yahoo.com>: Jun 16 11:15AM -0500 >but this gives error when p is 64 bit and int 32 bit. >I can cast to long but long does not have to be 64 bit,either. >What do you suggest? intptr_t and/or uintptr_t from cstdint. Although they don't have to exist. |
scott@slp53.sl.home (Scott Lurndal): Jun 16 04:28PM >but this gives error when p is 64 bit and int 32 bit. >I can cast to long but long does not have to be 64 bit,either. >What do you suggest? use the type 'uintptr_t' (C++11 and later) |
legalize+jeeves@mail.xmission.com (Richard): Jun 16 05:47PM [Please do not mail me a copy of your followup] Robert Wessel <robertwessel2@yahoo.com> spake the secret code >intptr_t and/or uintptr_t from cstdint. Although they don't >have to exist. It's kinda annoying that these are optional. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Melzzzzz <mel@zzzzz.com>: Jun 16 08:11PM +0200 On Tue, 16 Jun 2015 11:03:44 -0400 > I suggest the type that can contain the value. The standard does not > provide a type that fits, leaving it to the implementation. If > 'long' is not large enough, use 'long long'. Well, this is actually int passed as void*. Because of C interface generic parameter is void*. So I have to convert int -> void* -> int |
Melzzzzz <mel@zzzzz.com>: Jun 16 08:16PM +0200 On Tue, 16 Jun 2015 11:15:23 -0500 > >What do you suggest? > intptr_t and/or uintptr_t from cstdint. Although they don't > have to exist. Too ,bad ;( I need intptr_t as conversion is actually passing int parameter as void* and than back to int. |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 16 02:21PM -0400 On 6/16/2015 2:11 PM, Melzzzzz wrote: >> 'long' is not large enough, use 'long long'. > Well, this is actually int passed as void*. Because of C interface > generic parameter is void*. So I have to convert int -> void* -> int Read about 'reinterpret_cast' in your compiler documentation and see what limitations it sets. Please don't use a C-style cast, it's ugly, dangerous, difficult to search for if you want to know where in your code you're using it. V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): Jun 16 07:01PM [Please do not mail me a copy of your followup] Melzzzzz <mel@zzzzz.com> spake the secret code >> 'long' is not large enough, use 'long long'. >Well, this is actually int passed as void*. Because of C interface >generic parameter is void*. So I have to convert int -> void* -> int An alternative is to pass a pointer to the int instead of the int. Generally these C apis with void* context parameters are intending that you allocate a chunk of memory and pass the pointer around to the callbacks instead of raw values. This is more portable than trying to figure out how to convert between int and void*. Any pointer is implicitly convertible to a void* and you can static_cast any void* to a pointer of type T (although the result is undefined behavior of the void* didn't come from a pointer to type T). -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 16 03:14PM -0400 On 6/16/2015 3:01 PM, Richard wrote: > pointer is implicitly convertible to a void* and you can static_cast > any void* to a pointer of type T (although the result is undefined > behavior of the void* didn't come from a pointer to type T). Allocation of a plain int is often expensive in both memory and time, and besides, who owns that pointer and who's going to deallocate that memory when it's not needed anymore? What if a C API call happens periodically with the same value, do you propose to allocate it every time and deallocate after the call has returned? What if API is such that it needs to retain the value for a few calls? A literal would be much less trouble than managing the lifetime of a single 'int'. Not saying that such a solution is unacceptable, just that it's not necessarily easy or as clean as it might appear at a first glance. V -- I do not respond to top-posted replies, please don't ask |
Noob <root@127.0.0.1>: Jun 16 08:47PM +0200 On 15/06/2015 16:35, Richard wrote: >> int array[20] = { 0 }; > Value initialization: > <http://en.cppreference.com/w/cpp/language/value_initialization> I don't see the syntax suggested by Christian (type field_name = init_val;) in cppreference's grammar? I wrote the following test program: class foo { public: int i = 5; int array[5] = { 1, 2, 3 }; int uninit[100]; }; int main(void) { foo xx; foo *yy = new foo; foo *zz = new foo{}; foo *tt = new foo[20]{}; return xx.i + yy->i + zz->i + tt->i; } $ g++ -std=c++11 -Wall -Wextra -ggdb3 init.cpp (I note that c++11 support was considered incomplete and experimental in gcc 4.8) The "uninit" array seems to be initialized to 0 in all cases except xx. Is that by design or an accident of the allocator's design? What is the difference between new foo; and new foo{}; ? Regards. |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 16 02:59PM -0400 On 6/16/2015 2:47 PM, Noob wrote: >[..] > What is the difference between new foo; and new foo{}; ? 'new foo' default-initializes the object, 'new foo{}' performs the so called direct-initialization. They differ a bit. The one without the braces looks for a c-tor that can be called without the arguments, and if found, calls it. If none exist, it leaves the object uninitialized! The form with braces default-initializes the object, which in absence of any c-tors yet with member initializers, performs member-wise initialization using the initializers provided for each member. IOW, 'new foo' ignores the individuals member initializers while 'new foo{}' uses those. V -- I do not respond to top-posted replies, please don't ask |
legalize+jeeves@mail.xmission.com (Richard): Jun 16 07:04PM [Please do not mail me a copy of your followup] Noob <root@127.0.0.1> spake the secret code >> <http://en.cppreference.com/w/cpp/language/value_initialization> >I don't see the syntax suggested by Christian (type field_name = init_val;) >in cppreference's grammar? <http://en.cppreference.com/w/cpp/language/data_members> >The "uninit" array seems to be initialized to 0 in all cases >except xx. Is that by design or an accident of the allocator's >design? This is probably coming from the allocator and the fact that in your small program you haven't released any previously allocated memory back to the allocator for reuse. All memory obtained from the operating system (in modern operating systems, anyway) is zeroed before being given to the allocator in the C++ runtime. >What is the difference between new foo; and new foo{}; ? They both invoke the default constructor, so I'd say nothing. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Doug Mika <dougmmika@gmail.com>: Jun 16 10:43AM -0700 I have heard of having operator+ inside a class, to define the + operation on objects of that class. However, what if we have defined such an operator outside of any class(and on top of that we make it a template)? And, what is the purpose of -> and what it points to in: template<class T, class U> auto operator+(const Matrix<T>& a, const Matrix<U>& b) -> Matrix<decltype(T{}+U{})> { Matrix<decltype(T{}+U{})> res; for (int i=0; i!=a.rows(); ++i) for (int j=0; j!=a.cols(); ++j) res(i,j) += a(i,j) + b(i,j); return res; } |
legalize+jeeves@mail.xmission.com (Richard): Jun 16 06:03PM [Please do not mail me a copy of your followup] Doug Mika <dougmmika@gmail.com> spake the secret code >template<class T, class U> >auto operator+(const Matrix<T>& a, const Matrix<U>& b) -> >Matrix<decltype(T{}+U{})> { See item (2): <http://en.cppreference.com/w/cpp/language/auto> A template function often wants to say "my return type is the type resulting from some expression; dear compiler please figure that out for me". The mechanism for supporting this in C++11 is to declare the return type of the template function "auto" and then use -> to specify the return type with decltype. <http://en.cppreference.com/w/cpp/language/decltype> The "trailing return type" syntax can also be used with any function declaration, not just template functions. See <http://en.cppreference.com/w/cpp/language/function> -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Doug Mika <dougmmika@gmail.com>: Jun 16 08:49AM -0700 On Monday, June 15, 2015 at 4:30:15 PM UTC-5, Richard wrote: > The Computer Graphics Museum <http://computergraphicsmuseum.org> > The Terminals Wiki <http://terminals.classiccmp.org> > Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> Well, I had a look at the link you provided, I have actually seen it before, but it's not something I understand. Is there any chance that someone could quickly, in laymen terms, explain why the following function can be constexpr if it has a run-time variable as a parameter? And it's even allowed to call itself? constexpr int fac(int n) { return (n<2)?1:n*fac(n-1); } |
Bo Persson <bop@gmb.dk>: Jun 16 06:14PM +0200 On 2015-06-16 17:49, Doug Mika wrote: >> value for n as some integral type constant or constant expression. > Well, I had a look at the link you provided, I have actually seen it before, but it's not something I understand. Is there any chance that someone could quickly, in laymen terms, explain why the following function can be constexpr if it has a run-time variable as a parameter? And it's even allowed to call itself? > constexpr int fac(int n) { return (n<2)?1:n*fac(n-1); } It is constexpr if the parameter is known at compile time, like if it is itself constexpr or a literal. In that case the compiler is required to compute the value during compilation. And the result can be used as a constant. This doesn't in any way stop you from ALSO using the same function with a non-const parameter, but of course then it will be evaluated at runtime. Bo Persson |
Victor Bazarov <v.bazarov@comcast.invalid>: Jun 16 12:14PM -0400 On 6/16/2015 11:49 AM, Doug Mika wrote: > [...]Is there any chance that someone could quickly, in laymen > terms, explain why the following function can be constexpr if it has a run-time variable as a parameter? And it's even allowed to call itself? > constexpr int fac(int n) { return (n<2)?1:n*fac(n-1); } Write a small main program: int main(int argc, char *argv[]) { constexpr int fac10 = fac(10); } Is it OK? Now change the call to 'fac' to use not a constant by some run-time variable, like 'argc'. Is it still OK? Declaration of a function as 'constexpr' makes (a) the function itself inline, and (b) allows the function to be called in an expression that is expected to be 'const'. If the expression is not 'const', then 'constexpr' is simply ignored, I think. For instance, you can't do constexpr int fac_argc = fac(argc); // not allowed - 'argc' is not const but it's totally OK to do int fac_argc = fac(argc); in which case 'constexpr' doesn't matter. V -- I do not respond to top-posted replies, please don't ask |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Jun 16 06:29PM +0200 On 15.06.15 20.52, Richard wrote: > Cross-compilation and "not yet compiled" have nothing to do with > constexpr and static_assert. Well, constexpr forces a function to be deterministic, side effect free and compile time evaluable. Although the exact definition depends on the C++ standard version and includes some other constraints to ensure that it can be evaluated. The newer the standard the more is allowed. From my point of view this has to do with compilation. Marcel |
legalize+jeeves@mail.xmission.com (Richard): Jun 16 05:38PM [Please do not mail me a copy of your followup] Marcel Mueller <news.5.maazl@spamgourmet.org> spake the secret code >C++ standard version and includes some other constraints to ensure that >it can be evaluated. The newer the standard the more is allowed. From my >point of view this has to do with compilation. Again, this has nothing to do with "not yet compiled" and cross-compilation. Cross-compilation is compiling source code on one architecture that targets another architecture other than that which is hosting the compiler. This has nothing to do with constexpr. You don't even state precisely what you mean by "not yet compiled", so there isn't anything more to be said about that. If you mean that a constexpr function must be *defined* (and not just declared) in order to be called as part of constructing a larger constant expression, that is true. A function can be declared constexpr, but not yet defined in the current translation unit, and still be used to generate a value at runtime. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
legalize+jeeves@mail.xmission.com (Richard): Jun 16 02:18PM [Please do not mail me a copy of your followup] fl <rxjwg98@gmail.com> spake the secret code > BaseConstructor(int=0) > {} >}; Didn't we already go over this in another thread? It feels like a bunch of people are taking a summer course in C++ using a confusing and poorly written book and the instructor has recommended you come here for help. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
scott@slp53.sl.home (Scott Lurndal): Jun 16 09:54AM -0600 >> extended types, and where they have, they are often not portable (there >> is no guarantee that any of the exact types exist on a platform) >Can you back that assertion up with any facts at all? Probably not. Most of the C++ code that I've worked on over the last 20+ years uses these types (before they were standardized, and with names like u32, uint32, uint32_t etc). Granted most of that code ran sans OS (it was the OS), and required fixed types to map to various hardware registers. However, absent API requirements for other types, I would prefer using types for which I understand the characteristics in all conditions, thus I prefer the explicitly sized types. Having run into many issues in the past porting software from 16-bit ints to 32-bit ints (and from 32-bit longs to 64-bit longs), I would never advocating using 'int' for anything. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 16 05:02AM >B a[ 2 ]; >a[ 1 ].~B(); new( a + 1 )D(); // destroy old a[ 1 ] and place new a[ 1 ] >Why does this now still has undefined behavior? It seems that 3.8 deals with this and does only allow an object of exactly the same class to be placed at this storage. However, I found this in 9.5p4: »If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new operator as follows: u.m.~M(); new (&u.n) N;« This is looking very close to what I do, but then it doesn't really help me, because the information about which member is active is not available at run time. I could store this information myself, but this would mean to /reinvent/ polymorphism, while I want to /use/ the polymorphism of the language. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment