Ограничения не выполняются для концепции шаблона шаблона, требующего статического метода шаблона - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь реализовать Functor и другие теоретико-категоричные концепции, используя концепции C ++, но получаю ошибки компиляции:

http://coliru.stacked -crooked.com / a / e8b6eb387229bddf

Вот мой полный код (я знаю, что требование fmap<int, int> не проверяет fmap для любых двух типов, и я планирую изменить его на fmap<int, std::string> или что-то еще, чтобы получить немного более сильный тест -- или вместо этого, возможно, измените концепцию Functor, чтобы она в дополнение к F, два типа T и U и проверяла существование fmap<T, U>, но это все после того, как я выяснил, как исправитьошибка, которую я получаю):

#include <functional>
#include <iostream>
#include <vector>

// empty Functor_Impl struct - specialize for each functor
template<template<class> class F> struct Functor_Impl {};

// std::vector Functor implementation
template<>
struct Functor_Impl<std::vector> {
    template<class T, class U>
    static std::vector<U> fmap(std::vector<T> x, std::function<U(T)> f) {
        std::vector<U> out;
        out.reserve(x.size());
        for (int i = 0; i < x.size(); i++) {
            out.push_back(f(x[i]));
        }
        return out;
    }
};

// Functor concept requires Functor_Impl<F> to have fmap
template<template<class> class F>
concept bool Functor = requires(F<int> x) {
    {Functor_Impl<F>::template fmap<int, int>(x)} -> F<int>;
};

// Test function using constraint.
template<template<class> class F, class T>
requires Functor<F>
F<T> mult_by_2(F<T> a) {
    return Functor_Impl<F>::template fmap<T, T>(a, [](T x) {
        return x * 2;
    });
}

int main() {
    std::vector<int> x = {1, 2, 3};
    std::vector<int> x2 = mult_by_2(x);
    for (int i = 0; i < x2.size(); i++) {
        std::cout << x2[i] << std::endl;
    }
}

И ошибка компиляции:

lol@foldingmachinebox:~/p/website-editor$ g++ foo.cpp -std=c++17 -fconcepts -o foo
foo.cpp: In function ‘int main()’:
foo.cpp:39:38: error: cannot call function ‘F<T> mult_by_2(F<T>) [with F = std::vector; T = int]’
     std::vector<int> x2 = mult_by_2(x);
                                      ^
foo.cpp:31:6: note:   constraints not satisfied
 F<T> mult_by_2(F<T> a) {
      ^~~~~~~~~
foo.cpp:24:14: note: within ‘template<template<class> class F> concept const bool Functor<F> [with F = std::vector]’
 concept bool Functor = requires(F<int> x) {
              ^~~~~~~
foo.cpp:24:14: note:     with ‘std::vector<int> x’
foo.cpp:24:14: note: the required expression ‘Functor_Impl<F>::fmap<int, int>(x)’ would be ill-formed

Я предполагаю, что мой синтаксис для самой концепции неверен - что он лечитпеременная как функция, или наоборот, так как я не очень знаком с синтаксисом concept, и, кроме того, некоторые примеры кода на cppreference.com не компилируются при реализации GCC (например, concept EqualityComparable не компилируется,должно быть изменено на concept bool EqualityComparable).

Если я удаляю requires Functor<F> из объявления функции mult_by_2, то код компилируется и запускается.

1 Ответ

0 голосов
/ 20 мая 2018

Проблема именно в том, что сообщение об ошибке говорит: Functor_Impl<F>::template fmap<int, int>(x) не является допустимым выражением.Functor_Impl<std::vector>::fmap имеет два параметра, а не один.

...