Home > database >  Template argument deduction fails on C 14
Template argument deduction fails on C 14

Time:11-30

I was trying to compile this code but it fails on C 14 while it works on C 17

#include <cstdio>
#include <utility>

template <typename F>
struct S {
    explicit S(F&& fn): fn(std::move(fn)) {}
    F fn;
    ~S() { fn(); }
};


int main(){
    S obj([]() noexcept {
        std::printf("Foo\n");
    });                                                                                                 
}

I see that in C 17 the constructor of S has been invoked as

   call    S<main::{lambda()#1}>::S(main::{lambda()#1}&&)

which indicates that the compiler deduced the template argument. Is there a way to get this code compiling in C 14 other than doing something as follows?

auto fn = []() noexcept {
    std::printf("Foo\n");
};
S<decltype(fn)> obj(std::move(fn)); 

CodePudding user response:

Class template argument deduction (CTAD) was only introduced in C 17 . You can deduce the argument with a function:

template <typename F>
S<F> make_S(F&& fn) { return S<F>{std::forward<F>(fn)}; }

int main(){
    auto obj = make_S([]() noexcept {
        std::printf("Foo\n");
    });
}

CodePudding user response:

If you can live with a fixed function signature then this works in C 14 too.

#include <functional>
#include <iostream>
#include <utility>

struct S 
{
    template <typename F>
    explicit S(F&& fn) : 
        m_fn(fn)
    {
    }

    ~S() 
    { 
        m_fn(); 
    }

private:
    std::function<void ()> m_fn;
};


int main() {
    S obj([]() noexcept 
    {
            std::cout << "Foo\n";
    });

    return 0;
}
  • Related