Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.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++;11可变模板_C++_C++11_Variadic Templates_Variadic Functions - Fatal编程技术网

C++ 写一篇多维的文章;“数学函数”;使用C++;11可变模板

C++ 写一篇多维的文章;“数学函数”;使用C++;11可变模板,c++,c++11,variadic-templates,variadic-functions,C++,C++11,Variadic Templates,Variadic Functions,我想编写一个模拟数学函数行为的C++11类。该类将定义函数的集合作为输入,并且可以设置并获取与域中特定点关联的值 由于组成函数域的集合数量是未知的,我想使用C++11可变模板来定义类,如下所示: template<typename first_set_type, typename... additional_sets_type> class Function; Function<int, std::string, double> three_dim_function(S

我想编写一个模拟数学函数行为的C++11类。该类将定义函数的集合作为输入,并且可以设置并获取与域中特定点关联的值

由于组成函数域的集合数量是未知的,我想使用C++11可变模板来定义类,如下所示:

template<typename first_set_type, typename... additional_sets_type> class Function;
Function<int, std::string, double> three_dim_function(S1, S2, S3);
最有可能的是,
std::unordered_map
是存储域和编码域之间绑定的理想数据成员:

std::unordered_map<std::tuple<first_set_type, additional_set_types...>, double> data_;
std::无序的地图数据;
尽管这两个问题并不完全相同,我还是尝试从中改编代码(在我的情况下,我可能不需要存储每个
std::set

编辑#1:我会尽量强调我面临的问题。在链接问题中,类是通过递归调用创建的。然而,在我的例子中,我很难理解如何实现构造函数,即如何从输入集开始设置函数的域。一种可能的方法是使用构造函数预填充由
数据
数据成员的输入集的笛卡尔积生成的所有键。问题是我不知道如何迭代参数包

暂定解决方案#1
下面是一个初步的实现:基于@robert mason的贡献。不幸的是,只要调用
位于\u域()
,它就不会编译(clang 4.1,OSX 10.8.4)。然而,乍一看,一切似乎都很好。有什么问题吗?

我在下面留下我的原始答案,但我会尝试用可变模板来回答您的问题

对于可变函数模板,您不需要迭代参数包。您必须改为使用递归函数

然后我会使用类似于:

template <class FirstDomain, class ...Domains>
class Function {
public:
    typedef std::tuple<FirstDomain, Domains...> domain_t;
    static constexpr size_t dimension = sizeof...(Domains) + 1; //+1 for FirstDomain
private:
    std::tuple<std::set<FirstDomain>, std::set<Domains>...> domain;
    std::unordered_map<domain_t, double> map;

    template <size_t index = 0>
    typename std::enable_if<(index < dimension), bool>::type
    is_in_domain(const domain_t& t) const {
        const auto& set = std::get<index>(domain);
        if (set.find(std::get<index>(t)) != set.end()) {
            return is_in_domain<index + 1>(t);
        }
        return false;
    }
    template <size_t index = 0>
    typename std::enable_if<!(index < dimension), bool>::type
    is_in_domain(const domain_t& t) const {
        return true;
    }
public:
    Function(std::set<FirstDomain> f, std::set<Domains>... ds) :
        : domain(f, ds...) {}
};
three_dim_function.set(1, "a", 1.23, 12);
double twelve = three_dim_function.get(1, "a", 1.23);
如果你想让它看起来更好,你可以做一些语法糖:

template <class first_type, class ...addl_types>
class Function {
public:
    //...
    //left as an exercise for the reader
    void set(std::tuple<first_type, addl_types...>, double);

    class set_proxy {
        friend class Function<first_type, addl_types...>;
        std::tuple<first_type, addl_types...> input;
        Function<first_type, addl_types...>& parent;
        set_proxy(std::tuple<first_type, addl_types...> t, Function<first_type, addl_types...>& f)
            : input(t), parent(f) {}
        set_proxy(const set_proxy&) = delete;
        set_proxy& operator=(const set_proxy&) = delete;
    public:
        //yes, I know this isn't the right return type, but I'm not sure what's idiomatic
        void operator=(double d) {
            parent.set(input, d);
        }
    };

    set_proxy set(first_type f, addl_types... addl) {
        return set_proxy{std::make_tuple(f, addl...), *this};
    }
};
模板
类函数{
公众:
//...
//留给读者作为练习
空集(std::tuple,double);
类集合\代理{
友元类函数;
std::元组输入;
功能&父级;
set_代理(std::tuple t,Function&f)
:输入(t),父(f){}
set_proxy(const set_proxy&)=delete;
set_proxy&operator=(const set_proxy&)=delete;
公众:
//是的,我知道这不是正确的返回类型,但我不确定什么是惯用的
void运算符=(双d){
父集合(输入,d);
}
};
集合\代理集合(第一个\类型f,添加\类型…添加){
返回集_proxy{std::make_tuple(f,addl…,*this};
}
};
这样您就可以执行以下操作:

Function<int, std::string, double> three_dim_function;
three_dim_function.set(1, "a", 1.23) = 12;
功能三维功能;
三维函数集(1,“a”,1.23)=12;

问题是什么?你试过什么?我试着完全按照问题中的描述实现这个类。事实上,我没有提供代码,但我担心它不会有多大帮助。这就是为什么我更愿意描述我的问题。那么对于一个N维的
函数
,您设置的N元组是映射到值的
set()
还是映射到值的
get()
?在我看来,你只需要为一个值设置一个键。也就是说,你有一个元组映射还是一个元组映射?我有一个元组映射。因此,对于函数域中的每个点,即元组
(映射键),对应于编码域中的一个且仅一个点,即与元组关联的
值。感谢您的回答。如何处理未知数量的输入集?我不想按数学函数的每个维度创建一个类(例如,2DFunction,3dffunction)。我不理解你的问题。如果您看一下将处理所有这些问题的简短代码示例。您可以使用封闭类的可变参数包作为函数的参数类型。我更新了问题,希望问题现在更清楚。谢谢。输入集是有限的。
函数
类将形式为
(表示输入集数量的
n
)的每个元组与双标量相关联。由于函数仅为作为输入集笛卡尔积获得的点定义,因此必须提前知道提供给setter/getter的特定点是否确实是有效点。检查这一点的一种可能方法是在构造函数中为
数据创建所有可能的键。在setter和getter中,您可以使用
数据\uu.at(point)
来验证该点是否属于函数域。好的,谢谢,这更清楚了。给我一点时间,我来敲定一些事情。
Function<int, std::string, double> three_dim_function;
three_dim_function.set(1, "a", 1.23) = 12;