Search code examples
c++variadic-templates

Compose functions with template in C++ got segmentation fault


I'm trying to write a demo to chain various functions into one, just like chain(f, g)(x) = g(f(x)), it is OK when I chain lambdas, but with named functions, I got a segmentation fault, I'm now struggling with it.

My code:

template <typename F, typename G>
constexpr auto chain(F&& f, G&& g) {
  return [&](auto x) {
    return g(f(x));
  };
}

template <typename F, typename... Fs>
constexpr auto chain(F&& f, Fs&&... fs) {
  return chain(f, chain(fs...));
}

int add1(int x) {
  return x + 1;
}

int times2(int x) {
  return x * 2;
}

int add10(int x) {
  return x + 10;
}

int main(int argc, char* argv[]) {
  auto f = chain(
      [](int x) { return x + 1; },
      [](int x) { return x * 2; },
      [](int x) { return x + 10; });
  printf("result: %d\n", f(2)); // Here is OK
  auto g = chain(add1, times2, add10);
  printf("result: %d\n", g(2)); // Here I got a segmentation fault and I don't know why
  return 0;
}

Solution

  • Your non-variadic chain function template returns a lambda that captures the arguments f and g by reference. These references are dangling when you return from chain, and invoking the returned lambda invokes undefined behavior.

    As is the case with undefined behavior, it can appear to work sometimes, and can cause a segmentation fault at other times. There is of course no guarantee of this behavior.