Home >Backend Development >C++ >How Can I Efficiently Implement a Switch Statement with Non-Integer Arguments in C/C ?

How Can I Efficiently Implement a Switch Statement with Non-Integer Arguments in C/C ?

DDD
DDDOriginal
2024-11-28 07:25:14999browse

How Can I Efficiently Implement a Switch Statement with Non-Integer Arguments in C/C  ?

Non-Integer Arguments in C/C Switch Statements

The switch statement in C/C is a powerful control flow mechanism that allows for efficient branching based on integer values. However, it is often desirable to switch on non-integer values, such as strings or enums. This presents a challenge as switch statements only accept integer arguments.

Traditional Approaches

One traditional approach to handling non-integer switch arguments is to use a sequence of if statements:

if( str == "foo" )      ...
else if( str == "bar" ) ...
else                    ...

However, this approach is inefficient as it requires linear time complexity (O(n)) for n cases. A more efficient solution is to represent the non-integer values as integers, either using maps or nested ifs. However, these approaches can be complex and error-prone.

Binary Search with Macros

Using macros, it is possible to implement an unrolled binary search at compile time, allowing for a fast and syntax-friendly approach:

#define NEWMATCH
#define MATCH("asd")
  some c++ code
#define MATCH("bqr")
  ... the buffer for the match is in _buf
#define MATCH("zzz")
  ...  user.YOURSTUFF 
#define ENDMATCH(xy_match)

This macro will generate a function that takes a string as input and returns a boolean, implementing a binary search through the specified cases.

C 11 lambdas and initializer lists

In C 11, lambdas and initializer lists offer a more elegant and concise approach:

template<typename KeyType, typename FunPtrType>
void switchStatement(const KeyType& value, std::initializer_list<std::pair<const KeyType, FunPtrType>> sws) {
    std::lower_bound(sws.begin(), sws.end(), value, [&](const auto& a, const auto& b) { return a.first < b.first; });
    if (r != sws.end() && !cmp(val, *r)) { r->second(); } // else: not found
}
int main() {
    switchStatement<const char*, void(*())>("ger", {
        { "asdf", []{ printf("0\n"); } },
        { "bde", []{ printf("1\n"); } },
        { "ger", []{ printf("2\n"); } },
    });
    return 0;
}

Compile Time Trie

In modern C , C 11 metaprogramming techniques can be utilized to create a compile-time trie, an advanced data structure that can efficiently handle unsorted case branches:

#include <smile/cttrie/cttrie.h>

using namespace smile::cttrie;

// Define cases as string literals
trie<true, void()> s = {"foo", "bar"};

int main() {
  // Switch on a string
  s.switch_on("foo", []() { std::cout << "foo" << std::endl; });
  return 0;
}

The above is the detailed content of How Can I Efficiently Implement a Switch Statement with Non-Integer Arguments in C/C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn