|
Definitions of template functions must be in every translation unit*. Putting them in a .cpp file isn't going to work. * Technically the standard allows you to bypass this with export, but I can only think of two compilers that support it: Comeau and EDG.
|
# ? Dec 9, 2008 05:33 |
|
|
# ? Jun 10, 2024 07:11 |
|
That did it, what a stupid mistake.
|
# ? Dec 9, 2008 05:39 |
|
That reminds me. For some reason, as soon as I started my sun studio 12 project it allowed me to do just that: put template class declarations in a .hpp and their implementations in a .cpp that includes the .cpp, just like a normal class. And it worked fine. It was only later that I remembered that this has never worked for me before and I still haven't found out what I did to the project settings to make it go (edit) And here's another unrelated one while I'm here! A continuation on the project that involved all that boost::bind and boost::function stuff last week. A coworker came to me this morning and asked if it was possible to include the option of doing this thing another way. Currently the system looks something like the examples you guys gave me last week: code:
code:
My first thought was that while this would work, I and the project as a whole would gain nothing from this, and indeed, lose the ability to callback to static and free functions. I suppose I could ADD it to the current functionality, but then it would just be confusing, and I don't know how I'd set up the template (short of leaving out the second parameter and using void* mObjPtr, which is unsafe). Tell me, o people smarter than I am: is there any reason he'd want it this way besides style? Ciaphas fucked around with this message at 18:13 on Dec 9, 2008 |
# ? Dec 9, 2008 15:18 |
|
Ledneh posted:My first thought was that while this would work, I and the project as a whole would gain nothing from this, and indeed, lose the ability to callback to static and free functions. I suppose I could ADD it to the current functionality, but then it would just be confusing, and I don't know how I'd set up the template (short of leaving out the second parameter and using void* mObjPtr, which is unsafe). Not only do you lose the ability to do callbacks to static/free functions with the second method but you also lose the ability to keep collections of CDataContainer's which callback on different types, since the type of CDataContainer now depends on the type of the callback object. Seems a bit silly to me.
|
# ? Dec 9, 2008 20:37 |
|
If I have enum foo { ... }; and I write foo f = foo (); what can I expect the value of f to be? Zero, the lowest enum value, the enum value closest to zero, undefined? I tried reading the standard to figure it out but it didn't seem that clear. Maybe I just missed it though.
|
# ? Dec 9, 2008 20:46 |
|
Lexical Unit posted:If I have enum foo { ... }; and I write foo f = foo (); what can I expect the value of f to be? pre:To zero-initialize an object of type T means: — if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T; — if T is a non-union class type, each nonstatic data member and each base-class subobject is zero- initialized; — if T is a union type, the object’s first named data member89) is zero-initialized; — if T is an array type, each element is zero-initialized; — if T is a reference type, no initialization is performed. To default-initialize an object of type T means: — if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor); — if T is an array type, each element is default-initialized; — otherwise, the object is zero-initialized. Edit: That is somewhere in 8.5, sorry
|
# ? Dec 9, 2008 21:05 |
|
Yeah I found section 8.5, but I was only able to view the "Current C++ Standard Working Paper" because you apparently need a username and password to view ISO/IEC 14882:2003 and there didn't seem to be a way to get a username or password. (Talking about this site, fyi). And the current working paper has some parts about zero-initializing struck out, so it was all a bit confusing. For what it's worth, this code (on that compiler) will print out a 0, even though 0 is an invalid value for that enum. I guess I was wondering if it's 0 because that's what the standard says it should be, of it's 0 simply due to the compiler's implementation and this behavior is actually undefined according to the standard.
|
# ? Dec 9, 2008 21:36 |
|
Nippashish posted:Not only do you lose the ability to do callbacks to static/free functions with the second method but you also lose the ability to keep collections of CDataContainer's which callback on different types, since the type of CDataContainer now depends on the type of the callback object. Seems a bit silly to me. I had some vague inkling of that second fact too, but I was having trouble putting it into words. Thanks for that. The coworker did say, though, that mixing and matching callback-receipt types or even using static/free functions was unlikely, but he would not say that it was impossible. Hell, we're practically designing this thing as we go. So I feel I should leave it as is, with the boost::function/bind implementation, for sake of versatility. That being said, is there perhaps a PERFORMANCE advantage to using the second implementation? I can't see one, but then I'm new to boost (and really C++, on a longer scale). Performance isn't a priority, but it is "a nice thing to shoot for when convenient" here. (edit) Another really picky disadvantage, what if they don't want to call their callback-receipt member functions output() or whatever I specify? Not that it's a big deal in any way, but isn't that sort of cross-class dependence kind of a no-no?
|
# ? Dec 9, 2008 21:51 |
|
Ledneh posted:That reminds me. For some reason, as soon as I started my sun studio 12 project it allowed me to do just that: put template class declarations in a .hpp and their implementations in a .cpp that includes the .cpp, just like a normal class. And it worked fine. It was only later that I remembered that this has never worked for me before and I still haven't found out what I did to the project settings to make it go Ok, I've re-written this post several times now, and I think I've got the stupid stuff straight in my head. What I was finding in my test case was just the effects of the stuff I linked below. If you have implemented the template in a cpp file, and *used* it in that same cpp, then for all the combinations of templates parameters that you have used, it will be available to the rest of the code. If you try and use it for a combination not used in that cpp file, you will get unresolved externals. You could however, implment it in another cpp file with those other template paramters and everything would work fine for them, and you could have totally different implementations, I assume this just comes from template specialisation. Now, what's slightly more odd, and I'm less clear on, was that Visual Studio lets you implement the template multiple times, using the same template paramters, and it wont give linker issues about multiply defined symbols, though it only seems to use one of the implementations. EDIT: duh, this is the normal usage case, except normally they would all be defined with the same code. EDIT: Jesus, I'm just getting more and more convinced that VS is just doing weird and crazy stuff. You will only be able to use the functions you have actually called, as otherwise it won't have actually compiled them into the translation unit. So, if you really want to use this crazy way of making templates, use explicit instantiation, doing it any other way seems like a lesson in pain. In conclusion, I'm pretty sure what I originally typed was correct, you should only be able to use templates if they have been defined in the same translation unit, unless you use explicit template instantiation. Explicit Template Instantiation: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v7v91/index.jsp?topic=/com.ibm.vacpp7l.doc/language/ref/clrc16explicit_instantiation.htm digibawb fucked around with this message at 00:10 on Dec 10, 2008 |
# ? Dec 9, 2008 23:09 |
|
I came across this in some code today and wondered if it actually does anything?code:
|
# ? Dec 10, 2008 00:07 |
|
Subotai posted:I came across this in some code today and wondered if it actually does anything? It should make no difference at all.
|
# ? Dec 10, 2008 00:20 |
|
digibawb posted:EDIT: Jesus, I'm just getting more and more convinced that VS is just doing weird and crazy stuff. You will only be able to use the functions you have actually called, as otherwise it won't have actually compiled them into the translation unit. So, if you really want to use this crazy way of making templates, use explicit instantiation, doing it any other way seems like a lesson in pain. MSVC defers member function instantiation of template classes until they are referenced. I don't know if it actually violates the standard, except in that it won't diagnose errors of non-referenced methods, but eh.
|
# ? Dec 10, 2008 00:25 |
|
digibawb posted:It should make no difference at all. The second cast is superfluous, but the first one allows addressing at the byte level for the struct.
|
# ? Dec 10, 2008 00:26 |
|
Avenging Dentist posted:The second cast is superfluous, but the first one allows addressing at the byte level for the struct. He asked whether there was any point in casting back and forth, I was just answering that question Avenging Dentist posted:MSVC defers member function instantiation of template classes until they are referenced. I don't know if it actually violates the standard, except in that it won't diagnose errors of non-referenced methods, but eh. I'm not sure if it breaks standard compliance either, but I actually like the "feature". It can be handy for having things where the code for a specific function will only work for a certainly type, or class of type, say a pointer, but you will only use that function for that type/class of type. Having said that, I have to deal with 4-5 different compilers at work, so don't get to make use of it, but eh, whatever. digibawb fucked around with this message at 00:42 on Dec 10, 2008 |
# ? Dec 10, 2008 00:38 |
|
Ledneh posted:That being said, is there perhaps a PERFORMANCE advantage to using the second implementation? I can't see one, but then I'm new to boost (and really C++, on a longer scale). Performance isn't a priority, but it is "a nice thing to shoot for when convenient" here. There is probably some slight overhead to using boost::function, but I would expect it to be somewhere on the order of the performance difference between std::vector and a raw array. Ledneh posted:(edit) Another really picky disadvantage, what if they don't want to call their callback-receipt member functions output() or whatever I specify? Not that it's a big deal in any way, but isn't that sort of cross-class dependence kind of a no-no? That sort of cross class dependence is often unavoidable when using templates that operate on their parameter types; AFAIK the only solution is good documentation. I believe they are planning to put some machinery to handle this in the next standard, but someone else would have to fill you in on the specifics.
|
# ? Dec 10, 2008 00:52 |
|
Hi everyone. I've got an issue with random numbers. I'm doing a project in which I'm trying to make a bunch of little bacteria or animals or whatever (called Moops) run around a 2-dimensional grid and reproduce. When using C++'s standard random number function, I'm getting some behavior that's very obviously not random. Moops seem to travel in groups and go the same direction for long stretches of time. It's not entirely fixed, but it's just very clearly not random enough for my purposes. I've tried seeding the random numbers using system time; is there a better way to achieve closer-to-true-randomness?
|
# ? Dec 10, 2008 12:37 |
|
Martman posted:Hi everyone. I've got an issue with random numbers. How can you tell it's not random enough? Obviously it's not truly random, but I'd say it's more likely something in your movement algorithm that's causing this behaviour than the numbers being insufficiently random.
|
# ? Dec 10, 2008 13:21 |
|
Martman posted:Hi everyone. I've got an issue with random numbers. Boost has a very nice random number library, read more here Although I agree with the above poster that it is unlikely to be the cause of your problems. Just to cover all the bases- you're only seeding the RNG once, right?
|
# ? Dec 10, 2008 14:21 |
|
PT6A posted:How can you tell it's not random enough? Obviously it's not truly random, but I'd say it's more likely something in your movement algorithm that's causing this behaviour than the numbers being insufficiently random. Basically, I've got a vector of moops, and every time a timer event occurs I pass them one by one to my movement function. The move function does this to each moop: code:
EDIT: Welp, I guess that was the problem. I was seeding it with every function call. Now they seem to be moving randomly. Thanks for the help!
|
# ? Dec 10, 2008 15:01 |
|
I am picking up a legacy codebase written in C, and I'm having a problem related to function pointers. At some point there is a struct defined so:code:
Given that I can't bust straight in and radically alter the design, am I SOL here, or is there something I can do to make the above work with pointers to functions with an arbitrary number of parameters?
|
# ? Dec 10, 2008 17:06 |
|
HauntedRobot posted:Given that I can't bust straight in and radically alter the design, am I SOL here, or is there something I can do to make the above work with pointers to functions with an arbitrary number of parameters? code:
|
# ? Dec 10, 2008 17:50 |
|
Have you tried a typedef and just casting the function pointer when assigning?
|
# ? Dec 10, 2008 18:36 |
|
TSDK posted:I can think of a few options, but none of them are going to get you what you want with zero changes. The simplest and clearest change I can think of doing is to put the handler member into an anonymous union, e.g.: Anonymous unions are C++-only I believe. In C, an empty param list means (or used to mean) the function can take any number of arguments, not that it takes no arguments. There might be a GCC switch to turn that behavior back on.
|
# ? Dec 10, 2008 21:55 |
|
Comedy variadic function option.
|
# ? Dec 10, 2008 21:56 |
|
Ledneh posted:That being said, is there perhaps a PERFORMANCE advantage to using the second implementation? I can't see one, but then I'm new to boost (and really C++, on a longer scale). Performance isn't a priority, but it is "a nice thing to shoot for when convenient" here. Yes, if performance is important to you, then boost::function is simply not the way to go. Have a look at http://www.codeproject.com/KB/cpp/fastdelegate2.aspx if you want to look at better performing alternatives(the mere thought of allocating heap memory just to save a function pointer gives me the shivers). boost::function is nice with its flexibility and all, but I would never ever use it if dealing with performance critical/realtime systems.
|
# ? Dec 10, 2008 22:06 |
|
floWenoL posted:In C, an empty param list means (or used to mean) the function can take any number of arguments, not that it takes no arguments. There might be a GCC switch to turn that behavior back on. This is the pre-C89 behavior, and so far as I can tell GCC no longer supports it (c89 appears to be the oldest dialect you can specify). edit: You used to be able to get GCC to compile K&R C via the -traditional flag, but modern versions won't take that flag unless you only want the code preprocessed but not compiled Blotto Skorzany fucked around with this message at 22:41 on Dec 10, 2008 |
# ? Dec 10, 2008 22:18 |
|
Avenging Dentist posted:Comedy variadic function option. Depending on how nasty he's willing to make this code, he might be able to hack it together part-way with optional arguments
|
# ? Dec 10, 2008 22:21 |
|
Zerf posted:Yes, if performance is important to you, then boost::function is simply not the way to go. Have a look at http://www.codeproject.com/KB/cpp/fastdelegate2.aspx if you want to look at better performing alternatives(the mere thought of allocating heap memory just to save a function pointer gives me the shivers). This is a pretty stupid argument, and completely irrelevant to Ledneh, since he was just mentioning that he's not in desperate need of optimization. He's just using callbacks, which will 1) be copied a minimal number of times, and 2) called relatively infrequently. Is Boost.Function inappropriate for some use cases? Obviously. But your post is really just whining about how Boost.Function isn't savagely optimized enough without regard to the actual use of the library. Besides that, if you don't like heap allocation, just provide it an allocator. EDIT: Perhaps you should look at the Boost.Function history before providing outdated information (the article you linked uses Boost 1.33.1). Avenging Dentist fucked around with this message at 22:48 on Dec 10, 2008 |
# ? Dec 10, 2008 22:44 |
|
HauntedRobot posted:Given that I can't bust straight in and radically alter the design, am I SOL here, or is there something I can do to make the above work with pointers to functions with an arbitrary number of parameters? This is one of the major incompatibilities between C and C++; it doesn't usually cause problems, but congratulations, you've found a place where it does. You will have to either (1) change the old code to conform to C++ or (2) make sure that you're compiling the old code with a C compiler instead of a C++ compiler. The easiest route to (1) is to use a union of some sort. (2) will require you to keep the code in a separate compilation module from your C++ code; if you name this file with a .c extension, usually it will automatically get compiled as C, but if all else fails your compiler should have an option to force C language semantics (in gcc, this is -x c). The C89 language revision is independent of this. The C89 standard officially endorsed the new argument declaration syntax (int main(int argc, char **argv) {}), broke the old K&R syntax (int main() int argc; char **argc; {}), and introduced the syntax int foo(void) to explicitly declare that a function takes no arguments.
|
# ? Dec 10, 2008 23:31 |
|
rjmccall posted:The C89 language revision is independent of this. What does this even mean? I posit: nothing.
|
# ? Dec 10, 2008 23:34 |
|
That C89 did not change the meaning of void f()
|
# ? Dec 10, 2008 23:37 |
|
Well then I don't see what the problem is? Just keep maintaining the project in C89. Or be a real man and do this: code:
Avenging Dentist fucked around with this message at 23:53 on Dec 10, 2008 |
# ? Dec 10, 2008 23:49 |
|
I have a C++ question. I'm reading this code which is doing some a part of some plane regression and wondering why you may want to do the lines with question marks, or what they are actually doing. The pointer array is a one dimensional array holding a bunch of data points x,y,z,x,y,z,...etc.code:
|
# ? Dec 11, 2008 03:06 |
|
Adding an integral value N to a pointer foo *p increments the pointer's address by N*sizeof(foo). Basically whoever wrote that code is stupid because you don't need the casts and can set the stride to 3 instead of 3*sizeof(double)
|
# ? Dec 11, 2008 03:30 |
|
SimpleCoax posted:I have a C++ question. I'm reading this code which is doing some a part of some plane regression and wondering why you may want to do the lines with question marks, or what they are actually doing. The pointer array is a one dimensional array holding a bunch of data points x,y,z,x,y,z,...etc. Compilers can be weird, and sometimes crap like this compiles better, at least when it doesn't compile dramatically worse. In this case, though, I strongly suspect it's just typical beginner confusion about pointer arithmetic. EDIT: also what AD said.
|
# ? Dec 11, 2008 03:33 |
|
I need help clearing dynamic memory.code:
rawstorm fucked around with this message at 05:01 on Dec 11, 2008 |
# ? Dec 11, 2008 04:53 |
|
rawstorm posted:I need help clearing dynamic memory. None of that should even come close to compile and it is full of stuff that doesn't make sense. Post your actual code and we'll tell you your problem. Also, if you need a dynamic array of vector<int> why aren't you just using a vector< vector< int > >?
|
# ? Dec 11, 2008 04:56 |
|
That Turkey Story posted:None of that should even come close to compile and it is full of stuff that doesn't make sense. Post your actual code and we'll tell you your problem. Also, if you need a dynamic array of vector<int> why aren't you just using a vector< vector< int > >? It compiles and everything works fine except that there is a memory leak. I need to use an array of vector<int>'s instead of vector< vector< int > > because I need to modify elements inside the data structure and that is not efficient with vectors.
|
# ? Dec 11, 2008 05:00 |
|
rawstorm posted:It compiles and everything works fine except that there is a memory leak. I need to use an array of vector<int>'s instead of vector< vector< int > > because I need to modify elements inside the data structure and that is not efficient with vectors. No, that would not compile. It would do the opposite of compiling, which is to say that it would fail to compile. Also, I don't think you know what you are talking about w.r.t. vector efficiency.
|
# ? Dec 11, 2008 05:05 |
|
|
# ? Jun 10, 2024 07:11 |
|
rawstorm posted:It compiles and everything works fine except that there is a memory leak. I need to use an array of vector<int>'s instead of vector< vector< int > > because I need to modify elements inside the data structure and that is not efficient with vectors. That would come nowhere near close to compiling and the logic in it doesn't make sense even if it did. At least present partially functioning code that compiles. Also, a vector is just a dynamic array, so I don't know what you think is more efficient about dynamically allocating your own array instead.
|
# ? Dec 11, 2008 05:08 |