Skip to main content
deleted 14 characters in body
Source Link
user1430
user1430

No. In C++, you can't switch on strings, only integers (and the values you compare to must be constant).

ItBut it is theoretically possible to indirectlyindirectly switch withon strings by choosing a stable mapping from string to integer (such as a hash function), applying that to the constants as well as the string to switch on, and using that. Because the expression in a case statement must be a compile-time constant, you're likely going to want to write that hash or mapping yourself and not rely on anything Unreal provides, as it may not be sufficient for this purpose (it may not be stable across runs or versions, and it probably doesn't yield a compile-time constant).

FNV1a is a simple, decent hash function, and as a bonus can be implemented as a constexpr function in C++. This will let you write:

constexpr std::uint32_t fnv1a(const char* s) { ... };

...

switch(fnv1a(someString)) {
  case fnv1a("Foo"): ... break;
  case fnv1a("Bar"): ... break;
  default: ... break;
}

If you don't have a modern C++ compiler, you will be forced to manually hash the strings yourself and write the resulting constant values in the case statements, which is exceedingly cumbersome.

Frankly, I'd argue that if the comparison code in question isn't a performance bottleneck, you're better off not overcomplicating things and just doing if/else chains. If it is a performance bottleneck, it might be worth revisiting whether or not you can replace the strings in a broader, algorithmic sense as it will likely be a bigger performance win.

As always, your mileage may vary, and you'll want to engage the services of a profiler to ensure you're actually gaining something by adding this extra layer of indirection.

No. In C++, you can't switch on strings, only integers (and the values you compare to must be constant).

It is theoretically possible to indirectly switch with strings by choosing a stable mapping from string to integer (such as a hash function), applying that to the constants as well as the string to switch on, and using that. Because the expression in a case statement must be a compile-time constant, you're likely going to want to write that hash or mapping yourself and not rely on anything Unreal provides, as it may not be sufficient for this purpose (it may not be stable across runs or versions, and it probably doesn't yield a compile-time constant).

FNV1a is a simple, decent hash function, and as a bonus can be implemented as a constexpr function in C++:

constexpr std::uint32_t fnv1a(const char* s) { ... };

...

switch(fnv1a(someString)) {
  case fnv1a("Foo"): ... break;
  case fnv1a("Bar"): ... break;
  default: ... break;
}

If you don't have a modern C++ compiler, you will be forced to manually hash the strings yourself and write the resulting constant values in the case statements, which is exceedingly cumbersome.

Frankly, I'd argue that if the comparison code in question isn't a performance bottleneck, you're better off not overcomplicating things and just doing if/else chains. If it is a performance bottleneck, it might be worth revisiting whether or not you can replace the strings in a broader, algorithmic sense as it will likely be a bigger performance win.

As always, your mileage may vary, and you'll want to engage the services of a profiler to ensure you're actually gaining something by adding this extra layer of indirection.

In C++, you can't switch on strings, only integers (and the values you compare to must be constant).

But it is possible to indirectly switch on strings by choosing a stable mapping from string to integer (such as a hash function), applying that to the constants as well as the string to switch on, and using that. Because the expression in a case statement must be a compile-time constant, you're likely going to want to write that hash or mapping yourself and not rely on anything Unreal provides, as it may not be sufficient for this purpose.

FNV1a is a simple, decent hash function, and can be implemented as a constexpr function in C++. This will let you write:

constexpr std::uint32_t fnv1a(const char* s) { ... };

...

switch(fnv1a(someString)) {
  case fnv1a("Foo"): ... break;
  case fnv1a("Bar"): ... break;
  default: ... break;
}

If you don't have a modern C++ compiler, you will be forced to manually hash the strings yourself and write the resulting constant values in the case statements, which is exceedingly cumbersome.

Frankly, I'd argue that if the comparison code in question isn't a performance bottleneck, you're better off not overcomplicating things and just doing if/else chains. If it is a performance bottleneck, it might be worth revisiting whether or not you can replace the strings in a broader, algorithmic sense as it will likely be a bigger performance win.

As always, your mileage may vary, and you'll want to engage the services of a profiler to ensure you're actually gaining something by adding this extra layer of indirection.

added 901 characters in body
Source Link
user1430
user1430

No. In C++, you can't switch on strings, only integers. And (and the case comparisonsvalues you compare to must be constantsconstant).

It is theoretically possible to indirectly switch with strings by choosing a stable mapping from string to integer (such as a hash function), hashing both the comparison string andapplying that to the constants as well as the string to compare against, and switch on, and using that. Or by using any other stable method of mappingBecause the strings to integers.

Howeverexpression in a case statement must be a compile-time constant, that's fairly cumbersomeyou're likely going to want to write that hash or mapping yourself and not easily achieved with built-in UE4 typesrely on anything Unreal provides, as it may not be sufficient for this purpose ('FName' is essentially an integerit may not be stable across runs or versions, but stability isn't guaranteed in all casesand it probably doesn't yield a compile-time constant). You'd likely want to do this externally so you can control the

FNV1a is a simple, decent hash function entirely; use something like FNV1a, which can be implementedand as a 'constexpr' functionbonus can be implemented as a constexpr function in C++.:

constexpr std::uint32_t fnv1a(const char* s) { ... };

...

switch(fnv1a(someString)) {
  case fnv1a("Foo"): ... break;
  case fnv1a("Bar"): ... break;
  default: ... break;
}

This isn't likely toIf you don't have a modern C++ compiler, you will be worthwhile;forced to manually hash the strings yourself and write the resulting constant values in the case statements, which is exceedingly cumbersome.

Frankly, I'd argue that if the comparison code in question is notisn't a performance bottleneck, if-elseyou're better off not overcomplicating things and just doing if/else chains comparing the actual strings will be vastly easier to manage.

  If it isis a performance bottleneck, it might be worth revisiting whether or not you should investigate eliminatingcan replace the strings entirely along this code pathin a broader, algorithmic sense as it will likely be thea bigger performance win.

As always, your mileage may vary, and you'll want to engage the services of a profiler to ensure you're actually gaining something by adding this extra layer of indirection.

No. In C++, you can't switch on strings, only integers. And the case comparisons must be constants.

It is theoretically possible to indirectly switch by choosing a stable hash function, hashing both the comparison string and the constants to compare against, and switch on that. Or by using any other stable method of mapping the strings to integers.

However, that's fairly cumbersome and not easily achieved with built-in UE4 types ('FName' is essentially an integer, but stability isn't guaranteed in all cases). You'd likely want to do this externally so you can control the hash function entirely; use something like FNV1a, which can be implemented as a 'constexpr' function in C++.

This isn't likely to be worthwhile; if the code in question is not a performance bottleneck, if-else chains comparing the actual strings will be vastly easier to manage.

  If it is a performance bottleneck, you should investigate eliminating strings entirely along this code path, as it will likely be the bigger win.

No. In C++, you can't switch on strings, only integers (and the values you compare to must be constant).

It is theoretically possible to indirectly switch with strings by choosing a stable mapping from string to integer (such as a hash function), applying that to the constants as well as the string to switch on, and using that. Because the expression in a case statement must be a compile-time constant, you're likely going to want to write that hash or mapping yourself and not rely on anything Unreal provides, as it may not be sufficient for this purpose (it may not be stable across runs or versions, and it probably doesn't yield a compile-time constant).

FNV1a is a simple, decent hash function, and as a bonus can be implemented as a constexpr function in C++:

constexpr std::uint32_t fnv1a(const char* s) { ... };

...

switch(fnv1a(someString)) {
  case fnv1a("Foo"): ... break;
  case fnv1a("Bar"): ... break;
  default: ... break;
}

If you don't have a modern C++ compiler, you will be forced to manually hash the strings yourself and write the resulting constant values in the case statements, which is exceedingly cumbersome.

Frankly, I'd argue that if the comparison code in question isn't a performance bottleneck, you're better off not overcomplicating things and just doing if/else chains. If it is a performance bottleneck, it might be worth revisiting whether or not you can replace the strings in a broader, algorithmic sense as it will likely be a bigger performance win.

As always, your mileage may vary, and you'll want to engage the services of a profiler to ensure you're actually gaining something by adding this extra layer of indirection.

Source Link
user1430
user1430

No. In C++, you can't switch on strings, only integers. And the case comparisons must be constants.

It is theoretically possible to indirectly switch by choosing a stable hash function, hashing both the comparison string and the constants to compare against, and switch on that. Or by using any other stable method of mapping the strings to integers.

However, that's fairly cumbersome and not easily achieved with built-in UE4 types ('FName' is essentially an integer, but stability isn't guaranteed in all cases). You'd likely want to do this externally so you can control the hash function entirely; use something like FNV1a, which can be implemented as a 'constexpr' function in C++.

This isn't likely to be worthwhile; if the code in question is not a performance bottleneck, if-else chains comparing the actual strings will be vastly easier to manage.

If it is a performance bottleneck, you should investigate eliminating strings entirely along this code path, as it will likely be the bigger win.