Может ли лямбда-выражение передаваться в качестве параметра шаблона в C ++ 17? - PullRequest
2 голосов
/ 05 ноября 2019

Я прочитал несколько ответов на SO с лямбдами, передаваемыми в шаблоны классов, но по какой-то причине я не могу этого достичь ... Я использую g ++ версии 9 с использованием C ++ 17.

#include <string>

struct Type {
    Type();
    Type(int);
    int theVal();
};

template<typename Key, typename Value, Key(*KeyFunc)(Type t) = nullptr>
struct MyClass {
    MyClass(){}

    ~MyClass(){}

    void add(const Key key, const Value value){
         //do stuff
    }

    void add(const Value value){
         this->add(KeyFunc(value), value);
    }
};

int main(){
    MyClass<
      int,
      std::string,
      +[](Type t){
        return t.theVal();
      }
    > instance;

    Type value(100);

    instance.add(value);

    return 0;
}

Сообщение об ошибке говорит мне, что я не могу иметь лямбду в шаблоне.

1 Ответ

2 голосов
/ 05 ноября 2019

Да, но его нужно сначала объявить вне параметра шаблона, а лямбда должна быть без захвата:

auto lambda = [](Type t) {
    return t.theVal();
};

// Works, C++17 allows constexpr conversion for nttp
MyClass<int, Type, lambda> instance;

В C ++ 20 вы можете использовать параметр шаблона auto C ++ 17's *1004*. и лямбда непосредственно в параметрах шаблона:

constexpr auto noop = [](auto&& v) -> decltype(auto) {
    return static_cast<decltype(v)&&>(v);
};

template<typename Key, typename Value, auto KeyFunc = noop>
class MyClass {
    // ...
};

MyClass<
    int,
    Type,
    [](Type t) {
        return t.theVal();
    }
> instance;

C ++ 20 Живой пример

C ++ 17 Живой пример

...