Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Vanadium
Jan 8, 2005

Yes it should.

Adbot
ADBOT LOVES YOU

Vanadium
Jan 8, 2005

There is at least one C-inspired language that requires that return is used like a function with parentheses and all, as far as I can tell it is mostly because the compiler guy could not be bothered to specialcase return's syntax. :shobon:

Vanadium
Jan 8, 2005

Flobbster posted:

string is a template

basic_string is a template, string is a regular type :colbert:

Vanadium
Jan 8, 2005

It is implementation-defined :mad:

Vanadium
Jan 8, 2005

Why did you instantiate the enum then? :colbert:

Vanadium
Jan 8, 2005

But assignment is way more common than testing equality, so it deserves the shorter operator!

Vanadium
Jan 8, 2005

I do not want to mock the dude because he obviously did not know better and his compiler did not give sufficient warnings, but trying to free a bunch of dynamically allocated objects with

delete foo, bar, baz;

is pretty depressing. :(

Vanadium
Jan 8, 2005

As posted in ##c++ on freenode:
code:
iteration_begin:
std::vector<CGameEvent*>::iterator lIterator = mEvents.begin();
for(lIterator; lIterator != mEvents.end(); lIterator++)
{
	if((*lIterator)->Dirty())
	{
		DestroyEvent(*lIterator);
		//Yes this is a shame, but once we remove an element the iterator is invalidated
		// there is for sure a better way to handle this, we do not want to only break
		// as this would keep the remaining event from being iterated
		goto iteration_begin;
	}
	(*lIterator)->OnIterate(inDeltaT);
}

Vanadium
Jan 8, 2005

chocojosh posted:

Would it have been so hard to keep a second vector of invalid nodes and then invalidate those after the for loop?

Keeping a vector of invalid nodes does not solve the problem at all because that just replaces the Dirty() check with a check against the vector of invalid nodes. :(

The proper solution (edit: which is not directly compatible with the guy's architecture, yeah) looks like
code:
for (iterator it = v.begin(); it != v.end(); ) {
  if (condition)
    it = v.erase(it);
  else
    ++it;
}
or, more functionally, v.erase(std::remove_if(v.begin(), v.end(), conditionfunctor), v.end()); (both from ##c++'s handy bot).

Vanadium fucked around with this message at 20:04 on Jul 31, 2008

Vanadium
Jan 8, 2005

Mustach posted:

You're both missing the real problem. DestroyEvent() takes a CGameEvent* (or CGameEvent*&); it's not invalidating any iterators. So, that comment is ironic, because the remaining events won't be iterated. mEvents.begin() isn't going to change, so re-accessing or deleting that element that got destroyed on the first iteration will probably crash the program.

I assumed that DestroyEvent was going to modify the vector on its own, looking up the element being destroyed by value.

Vanadium
Jan 8, 2005

Sounds like it should be easily possible to make foo == any_of(bar, baz, qux) work in C++, if some boost lib does not already.

Vanadium
Jan 8, 2005

Flobbster posted:

This is also CRAZY and going way out of one's way to implement what amounts to syntactic sugar for a sequence of OR comparisons :psyduck:

So basically you are saying it is going to be in the next boost release?

Edit: Based on your example, seems to work with gcc 4.3.1:

code:
#include <iostream>

template <typename T, typename Other>
bool is_one_of(T lhs, Other rhs) {
  return lhs == rhs;
}

template <typename T, typename First, typename... Rest>
bool is_one_of(T lhs, First rh, Rest... rhs) {
  return lhs == rh || is_one_of(lhs, rhs...);
}

int main() {
  if (is_one_of(1, 3, 4, 1, 2, 5)) 
    std::cout << "yay" << std::endl;

  if (is_one_of<std::string>("foo", "bar", "baz", "foo")) 
    std::cout << "yay 2" << std::endl;
}
I would still prefer to have the 'a == any_of(b, c, d)" syntax because it is easier to read and probably makes it easy to overload other operators than == as well. I did not bother with the whole "taking template arguments by const reference" thing because you probably need to use boost.call_traits to do it correctly, and I have no idea how to apply that to variadic templates.

Vanadium fucked around with this message at 22:33 on Aug 27, 2008

Vanadium
Jan 8, 2005

I got pretty much as far, except I did the recursion by composition and not inheritance, but then I tried to wrap boost::call_traits<T>::param_type around everything to avoid needless copying and it all fell apart. :(

Edit: I guess they just gently caress with argument deduction. How does this perfect forwarding thing work again...

Any ideas how to make it require less copying?

code:
#include <iostream>
#include <string>

template<typename... ArgsT>
struct any_impl;

template<typename FirstT>
struct any_impl<FirstT> {
  any_impl(FirstT first) : first(first) {}

  FirstT first;
};

template<typename FirstT, typename... OtherTs>
struct any_impl<FirstT, OtherTs...> {
  any_impl(FirstT first, OtherTs... others)
    : first(first), others(others...) {}

  FirstT first;
  any_impl<OtherTs...> others;
};

template<typename T, typename AnyT>
bool operator==(T obj, const any_impl<AnyT>& any) {
  return obj == any.first;
}

template<typename T, typename FirstT, typename... OtherTs>
bool operator==(T obj, const any_impl<FirstT, OtherTs...>& any) {
  return obj == any.first || obj == any.others;
}

template<typename T, typename AnyT>
bool operator==(const any_impl<AnyT>& any, T obj) {
  return obj == any.first;
}

template<typename T, typename FirstT, typename... OtherTs>
bool operator==(const any_impl<FirstT, OtherTs...>& any, T obj) {
  return any.first == obj || any.others == obj;
}

template<typename... ArgTs>
any_impl<ArgTs...> any_of(ArgTs... args) {
  return any_impl<ArgTs...>(args...);
}

// "trace" copying
template<typename T>
struct verbose {
  verbose(T val) : val(val) {
    std::cout << " verbose( " << val << " )" << std::endl;
  }

  verbose(const verbose& other) : val(other.val) {
    std::cout << " verbose([" << val << "])" << std::endl;
  }

  ~verbose() {
    std::cout << "~verbose( " << val << " )" << std::endl;
  }

  bool operator==(const verbose& other) const {
    std::cout
      << " verbose( " << val << " ) == verbose( "
      << other.val << " )" << std::endl;
    return val == other.val;
  }

  T val;
};

int main() {
  if (any_of(4, 3, 2, 1) == 1)
    std::cout << "yay" << std::endl;

  if (std::string("foo") == any_of("foo", "bar", "baz"))
    std::cout << "yay 2" << std::endl;

  verbose<int> v1(1), v2(2), v3(3), v4(4);
  if (any_of(v1, v2, v3, v4) == verbose<int>(5))
    std::cout << "yay 3" << std::endl;
}

Vanadium fucked around with this message at 00:44 on Aug 28, 2008

Vanadium
Jan 8, 2005

RegonaldPointdexter posted:

I saw this in some JavaScript yesterday:

code:
var change = true;
change = false;
while(change) {
  change = false;
No, I didn't remove any lines inbetween. It was exactly like this.

Looks like the loop would potentially reset change to true if it turned out it did not actually want to exit, and the first "change = false" is just a quick hack to disable the loop entirely.

Vanadium
Jan 8, 2005

Anonymous Name posted:

It's exactly like a pointer in implementation, of course.

Pointers behave nowhere near exactly like this:

code:
#include <string>
#include <iostream>

std::string f() { return "yay"; }

int main() {
  const std::string& s = f();

  std::cout << s.size() << " - " << s;
}

Vanadium
Jan 8, 2005

I am not really willing to give up the convinience of using references for "out" parameters just so you guys do not have to look up the function, sorry guys :shobon:

Vanadium
Jan 8, 2005

floWenoL posted:

If you were using Perl you'd be able to type 5_000_000. :colbert:

We can probably come up with something that lets you type num<5,000,0wait this is not going to work :(

Vanadium
Jan 8, 2005

Standish posted:

gently caress octal seriously, has anyone ever encountered it where it wasn't causing a weird bug with leading zeroes?

chmod(1) :geno:

Vanadium
Jan 8, 2005

meba rhodium posted:

I've been trying to wrap my head around this one line of code for hours and I still have no idea.

What does it look like if you just view the preprocessed code?

Vanadium
Jan 8, 2005

So would you prefix a smart pointer object variable with p?

Vanadium
Jan 8, 2005

JoeNotCharles posted:

How do you get int confused with FILE * and not notice?

Well, if he is calling it like FILE* f = open("foo", O_RDONLY); and not getting a warning for that conversion either, the whole thing might just work!

Vanadium
Jan 8, 2005

Ruby does not catch the ^C exception from a "begin; rescue; end", you actually need to go up the Exception inheritance thing to explicitly catch everything.

Vanadium
Jan 8, 2005

A logic error that deserves to be punished with undefined behaviour~

Vanadium
Jan 8, 2005

ashgromnies posted:

who the gently caress in the history of computing thought, "ah, yes, xml is a decent markup language for organizing data... let's make code out of it"

It worked for lisp

Vanadium
Jan 8, 2005

Guys, I am sure the .toString() calls get inlined...

Vanadium
Jan 8, 2005

That just makes the code more portable. In Ruby it is common practice to call .to_s on string-like objects

Vanadium
Jan 8, 2005

Mustach posted:

You can't subclass java.lang.String.

welp, you can in C++ using gcj's java interface.

Vanadium
Jan 8, 2005

Please tell me that was actually a system and not an exec. :(

Edit: Ignore me, I got my sigil'ing languages mixed up.

Vanadium
Jan 8, 2005

Triple Tech posted:

At first I was with you. But I can count at least three strikes against Perl. The function, the param, and the echo. And no my, how dare they.

I figured exec did the same thing everywhere and did not actually look that closely :(

Yeah, perhaps I just assumed the perl guys had come up with a reasonable function definition syntax since I last played with it, but I guess that would be stupid :mad:

Vanadium
Jan 8, 2005

mr_jim posted:

It took me a while to notice the problem with that code. I kept thinking "Well, it looks reasonable...

I kept trying to figure out how it would arrive at a wrong answer and could not come up with anything. :shobon:

Vanadium
Jan 8, 2005

I ended up realising that I was looking for the wrong thing, yeah.

Vanadium
Jan 8, 2005

That might be faster, but it is not a really generic solution to the problem.

code:
template<typename T>
bool is_odd(typename boost::call_traits<T>::param_type i) { 
  std::ostringstream ss;
  ss << i;
  std::string s(ss.str());
  char c = *s.rbegin();
  return ((char) (c * 128)) / -128;
}

Vanadium
Jan 8, 2005

Smackbilly posted:

Can't wait for C++0x lambda functions to make STL predicates so much less a pain in the rear end.

Oh, but there is already boost.phoenix


to tempt you with the prospect of making STL predicates so very elegant and easy, only to drown you in an ocean of template errors if you actually try to use it


:smith:

Vanadium
Jan 8, 2005

ymgve posted:

But nobody did that. The only person that did was in the example above you. The Python code is 100% valid and safe, because the formatting part is a literal.

That was just an explanation how to possibly get it wrong in C, because defending against that is what the dude did in Python. The joke is not that the python guy did something unsafe, it is that he used formatting operations to protect against a danger that does not even come with Python's print function.

Vanadium
Jan 8, 2005

It just is undefined, since both the assignment itself and the ++ modify i, which is illegal because there is no sequence point inbetween.

Vanadium
Jan 8, 2005

no this is not "who knows what the value of i is going to be afterwards", this is literally undefined behaviour

you do not have to argue why it is because it just says in the standard not to do that poo poo

Vanadium
Jan 8, 2005

Triple Tech posted:

Some "developers" don't know of platform agnostic interfaces to system commands...

Are you suggesting that some dude is trying to avoid hardcoding a WinAPI call in order to stay portable? It is not like del is.

Edit: It appears you are, in fact, not. Carry on.

Vanadium fucked around with this message at 19:14 on May 13, 2009

Vanadium
Jan 8, 2005

It's C++. I do not know any, either.

Vanadium
Jan 8, 2005

I could have sworn that was only POSIX. Hooray for standards. :3:

Adbot
ADBOT LOVES YOU

Vanadium
Jan 8, 2005

Mustach posted:

I don't buy type erasure as the excuse for not being able to say new T[n]. That expression doesn't even need any type information since the elements are all initialized to null and no other "T" methods are used.

It's just another reason to not use Java arrays for anything but varargs.

It needs to plug the type T into the array type at some point so RTTI can proceed to ask for the array's type. Which does not work if T gets erased.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply