Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板参数的演绎指南_C++_Templates_Parameters_C++17_Deduction Guide - Fatal编程技术网

C++ 模板参数的演绎指南

C++ 模板参数的演绎指南,c++,templates,parameters,c++17,deduction-guide,C++,Templates,Parameters,C++17,Deduction Guide,我有一套结构类: template<typename T> struct Foo { T x_; T y_; constexpr Foo(T x, T y) : x_{x}, y_{y} {} }; template<typename T, typename U, template<U> class Func> class Bar { private: Foo<T> foo_; Func<U>

我有一套结构类:

template<typename T>
struct Foo {
    T x_;
    T y_;
    constexpr Foo(T x, T y) : x_{x}, y_{y} {}
};

template<typename T, typename U, template<U> class Func>
class Bar {
private:
    Foo<T> foo_;
    Func<U> func_
    size_t n_;
public:
    Bar(Foo<T> foo, size_t n, Func<U> func) :
      foo_{foo},
      n_{n},
      func_{func}
    {}
};


编辑-本节面向用户:

注意:上面是一个伪代码,其签名与我的类的表示形式相同。。。现在我又可以访问我的IDE了,这里是“真正的”源代码

Integrator.h

#pragma once

//#include <type_traits>

template <typename Field>
struct Limits {
    Field lower;
    Field upper;

    constexpr Limits(Field a = 0, Field b = 0) : 
        lower{ a < b ? a : b }, 
        upper{ a < b ? b : a }
    {}
};    

template <typename LimitType, typename Func>
class Integrator {       
    //static_assert(std::is_invocable_v<Func&>, "Invalid callable");
private:
    Limits<LimitType> limits_;
    size_t step_size_;
    Func integrand_;

public:
    Integrator(Limits<LimitType> limits, size_t stepSize, Func integrand) :
        limits_{ limits },
        step_size_{ stepSize },
        integrand_{ integrand }
    {}

    constexpr auto evaluate() {
        auto distance = limits_.upper - limits_.lower;     
        auto dx = distance / step_size_;       
        return calculate(dx);
    }        

private:
    template<typename ValueType>
    constexpr auto calculate(ValueType dx) {
        ValueType result = 0.0;
        for (size_t i = 0; i < step_size_; ++i) {
            auto dy = integrand_(limits_.lower + i * dx);
            auto area = dy * dx;
            result += area;
        }
        return result;
    }

};

//template <typename LimitType, typename Func>
//Integrator(Limits<LimitType>, size_t, Func)
//->Integrator<LimitType, Func>;
#pragma一次
//#包括
模板
结构极限{
场低;
田上;
constexpr限制(字段a=0,字段b=0):
下{a积分器;
main.cpp

#include <iostream>
#include <exception>

#include "Integrator.h"


double funcE(double x) {
    return x;
}

template <typename T>
constexpr T funcA_t(T x) {
    return x;
}    

// This Works! 
int main() {
    try {
        std::cout << "Integration of f(x) = x from a=3.0 to b=5.0\nwith an expected output of 8\n";
        Integrator integratorA{ Limits{3.0, 5.0}, 10000, funcA };
        std::cout << integratorA.evaluate() << '\n';    
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

// This was failing to compile... but now seems to work for some reason...
int main() {
    try {
        std::cout << "Integration of f(x) = x from a=3.0 to b=5.0\nwith an expected output of 8\n";
        Integrator integratorA{ Limits{3.0, 5.0}, 10000, funcA_t<double> };
        std::cout << integratorA.evaluate() << '\n';    
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

// Same as above...
Integrator integrator{ Limits{3.0, 5.0}, 10000, &funcA_t<double> };
// wasn't compiling...
#包括
#包括
#包括“Integrator.h”
双函数(双x){
返回x;
}
模板
constexpr T funcA_T(tx){
返回x;
}    
//这管用!
int main(){
试一试{

std::cout首先,使用以下语法:

template <typename T, typename U, template <U> class Func>
以及相应的扣减指引:

template <typename T, typename U, template <typename> class Func>
Bar(Foo<T>, U, Func<U>) -> Bar<T, U, Func>;
为了确保它可以用
U
类型的(左值)参数调用,只需设置一个类似于
static\U assert
的约束:

#include <type_traits>

template <typename T, typename U, typename Func>
class Bar {
    static_assert(std::is_invocable_v<Func&, U&>, "Invalid callable");
private:
    Foo<T> foo_;
    Func func_;
    U n_;
public:
    Bar(Foo<T> foo, U n, Func func) :
      foo_{foo},
      func_{func},
      n_{n}
    {}
};
或者,如果
需要,您可以使用
std::enable\u使
calculate
SFINAE友好:

template <typename ValueType>
constexpr auto calculate(ValueType dx)
    -> std::enable_if_t<std::is_invocable_v<Func&, ValueType&>, ValueType> {
    ValueType result = 0.0;
    // ...
    return result;
}
模板
constexpr自动计算(ValueType dx)
->std::如果启用,则启用{
ValueType结果=0.0;
// ...
返回结果;
}

U
您传递给
bar1
U
int
funcA
double(*)(double)
。对于某些
F
来说,这不是
F
。这不起作用…@Barry,
U
不应该是
int
它应该是
double
传递的
函数对象的
模板参数
,这就是我被难住的地方…好吧,
double(*)(double)
也不能推导到
F
。你确定不想只推导一个可调用的
F
?是的,在模板化这个类之前,我最初使用
std::function
作为这个参数。现在我正在尝试模板化它,并使它显式地
constepr
。我的函数的签名是
double func>(双x)
但现在它们也被模板化了。只使用单个参数并返回相同的类型。类的最后一个参数可以是单个变量的函数指针、函数对象、函子或lambda表达式。类将从其构造函数中存储它,并在其成员函数中调用它。您的示例很好,但e成员
n
不是
U
,而是
size\U t
t
是模板结构
Foo
将使用的类型,
U
应该是
函数对象
函数指针
函数
函数
lambdas>传入时将使用的类型这是
Bar
s成员函数的返回类型所必需的…
U Bar::someInternalFunc()
。如果这对您有意义的话?它们需要在类型上匹配。但是,这个类在传递到构造函数之前对这些函数对象一无所知…@FrancisCugler我认为
size\u t
是一个输入错误,因此我建议使用隐式推断指南。如果不是输入错误,那么就编写一个自定义推断ide。@FrancisCugler告诉我调用
func\u
的位置和方式。否则,这只是猜测您实际需要什么。@FrancisCugler将
static\u assert
放在
calculate
函数中。如果该函数的参数与存储的可调用obejct不匹配,则是该函数的问题,而不是类本身的错误。
template <typename T, typename U, template <typename> class Func>
Bar(Foo<T>, U, Func<U>) -> Bar<T, U, Func>;
template <typename T, typename U, typename Func>
//                                ~~~~~~~^
#include <type_traits>

template <typename T, typename U, typename Func>
class Bar {
    static_assert(std::is_invocable_v<Func&, U&>, "Invalid callable");
private:
    Foo<T> foo_;
    Func func_;
    U n_;
public:
    Bar(Foo<T> foo, U n, Func func) :
      foo_{foo},
      func_{func},
      n_{n}
    {}
};
template <typename ValueType>
constexpr auto calculate(ValueType dx) {
    static_assert(std::is_invocable_v<Func&, ValueType&>, "Invalid value type");
    ValueType result = 0.0;
    // ...
    return result;
}
template <typename ValueType>
constexpr auto calculate(ValueType dx)
    -> std::enable_if_t<std::is_invocable_v<Func&, ValueType&>, ValueType> {
    ValueType result = 0.0;
    // ...
    return result;
}