首页 > 解决方案 > 在 C++ 模板中将类型传递给 Lambda 函数

问题描述

我正在尝试std::transform在模板功能中使用。由于模板函数需要处理的类型有很多种,关键部分是 lambda 函数的设计std::transform。我想传递可迭代的基本类型T来构造一个 lambda 函数。这里使用的实验代码使用gcc 10.2typename std::iterator_traits<T::iterator>::value_typeMSVC 19.27 成功编译,但使用 clang 失败

我换了之后

typename std::iterator_traits<T::iterator>::value_type

进入

typename std::iterator_traits<typename T::iterator>::value_type

问题似乎解决了。但是,我不确定这是否是正确的用法。此外,如果还有其他更好的方法可以做到这一点,请告诉我。

template<typename T>
concept ElementSummable = requires(T x)
{
    x.at(0) + x.at(0);
};

template<typename T>
concept Iterable = requires(T x)
{
    x.begin();      // must have `x.begin()` 
    x.end();        // and `x.end()` 
};

template<class T> requires Iterable<T> && ElementSummable<T>
static T Foo(const T _input);

template<class T> requires Iterable<T> && ElementSummable<T>
static inline T Foo(const T _input)
{
    T returnObject = _input;
    std::transform(_input.begin(), _input.end(), returnObject.begin(),
        [](typename std::iterator_traits<T::iterator>::value_type element)->typename std::iterator_traits<T::iterator>::value_type
        {
            return element + 1;         //  For example
        }
    );
    return returnObject;
}

int main()
{
    long double number = 1;
    std::vector<decltype(number)> testVector1;
    testVector1.push_back(number);
    testVector1.push_back(number);

    std::cout << Foo(testVector1).at(0);
    return 0;
}

标签: c++templateslambdag++clang++

解决方案


问题是CLang编译器相对于标准的僵化。

问题不在于类型(这是正确的),问题在于您必须将 typename 放在依赖于模板的类型之前。

但是最好的解决方案是使用auto让编译器自己推断类型。


推荐阅读