标签: generic-programming

如何创建一个容器,每个对象一个?

我试图为可以附加到我的对象的可能元数据创建一个容器.我可以保证每类最多只有一个对象附加到我的班级,但是对于不同类型的对象没有限制.例如,我不能将两个实例附加wordInfo到一个对象,但是wordInfo和的实例phraseInfo可以同时附加到一个对象.这是我到目前为止完成的工作.

class object
{
    std::map <std::type_info, object*> mMetaData;
    public:
    inline void attachMetaData(object* pData)
    {
        mMetaData[typeid(*pData)] = pData;
    }
    template <class T> inline std::enableif<std::is_base_of<object,T>::value, T*>::type getMetaData()
    {
        if (mMetaData.find(typeid(T)) == mMetaData.end())
            return NULL;
        else
            return mMetaData[typeid(T)];
    }
    template <class T> inline std::enableif<std::is_base_of<object,T>::value, void>::type detachMetaData()
    {
        mMetaData.erase(typeid(T));
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码有一个编译错误:没有定义更少的运算符std::type_info所以我专门定义了一些较少的类std::type_info,并将它作为map类的第三个模板参数传递,如下所示:

struct typeinfoless
{
    bool operator()(std::type_info& left, std::type_info& right)
    {
        return left.hash() < right.hash();
    }
}
std::map <std::type_info, object*, typeinfoless> mMetaData;
Run Code Online (Sandbox Code Playgroud)

但后来我遇到了另一个错误,我不知道如何解决,std::type_info …

c++ stl generic-programming typeid typeinfo

2
推荐指数
1
解决办法
1136
查看次数

Haskell中的函数类型特化

我有一个具有类型的函数Read a => String -> a,是有可能有难同当,做不同的事情同名的另一个功能a是例如String?是否有任何GHC扩展允许这样做?

就像是:

f :: Read a => String -> a
f = read

f :: String -> String
f = id
Run Code Online (Sandbox Code Playgroud)

haskell types generic-programming ghc

2
推荐指数
1
解决办法
184
查看次数

在多种类型上推广一个新的运算符

我使用Unquote并没有看到任何近似的内容.所以我决定写一个.

let inline (=~=) x y = abs x-y <  1.E-10
Run Code Online (Sandbox Code Playgroud)

然而,运营商没有映射到Lists上

let test  = [1;2] =~= [1;2]  //---> error
Run Code Online (Sandbox Code Playgroud)

是否可以声明此运算符流动如何(=)

或者它需要定义像'StructuralEquality-ishness'这样的新特征?

使用http://code.google.com/p/fsharp-typeclasses/来定义新的运算符是否更好?

f# generic-programming functor typeclass f#-unquote

2
推荐指数
1
解决办法
204
查看次数

如何表达独立的数据值组合的模式匹配?

data Foo = Bar1
         | Bar2 Foo Foo
         | Bar3 Foo
         | Bar4 Foo Foo Foo
Run Code Online (Sandbox Code Playgroud)

现在,假设有人构建了一个Foo树,我想检查Foo值的参数是否有效.构造函数参数的规则是:

  • Bar2 Bar1 Foo
  • Bar3 (Bar2|Bar3|Bar4)
  • Bar4 Bar1 Bar1 (Bar1|Bar4)

我知道值的构造函数,只想检查立即参数,没有任何递归.像这样:

bar2 Bar1 Bar1      = True
bar2 Bar1 (Bar2 {}) = True
bar2 Bar1 (Bar3 _)  = True
bar2 Bar1 (Bar4 {}) = True
bar2 _ _ = False
Run Code Online (Sandbox Code Playgroud)

例如Bar4:

bar4 Bar1 Bar1 Bar1      = True
bar4 Bar1 Bar1 (Bar4 {}) = True
bar4 _ _ _ = False
Run Code Online (Sandbox Code Playgroud)

我怎样才能最简洁地表达这些条件?列出所有组合在某些情况下有点太多了.据我所知,不存在用于模式匹配的"OR"-syntax.

UPDATE

我改编了Daniel的解决方案并且已经解决了这个问题: …

haskell pattern-matching generic-programming gadt

2
推荐指数
1
解决办法
148
查看次数

由类参数检查的泛型类型参数可以被黑客攻击,有更好的方法吗?

考虑班级:

class OnlyIntegerTypeAllowed<T> {
    OnlyIntegerTypeAllowed(Class<T> clazz) {
        System.out.println(clazz);
        if (clazz != Integer.class)
            throw new RuntimeException();
    }
}
Run Code Online (Sandbox Code Playgroud)

它被设计为只接受Type Arguments Integer.我们if-throw在其构造函数中添加了一个检查.这是检查类型参数的一种非常常见的方法.

但是,可以通过以下方式绕过(黑客入侵,欺骗)此检查:

OnlyIntegerTypeAllowed<Integer> normalWay =
        new OnlyIntegerTypeAllowed<Integer>(Integer.class);
OnlyIntegerTypeAllowed<String> hacking =
        new OnlyIntegerTypeAllowed<String>((Class<String>) Class.forName(Integer.class.getName()));
Run Code Online (Sandbox Code Playgroud)

无论上述两行有没有编译错误和没有抛出异常!

OMG - 强制执行Type Argument的更好方法吗?

java generics class generic-programming type-parameter

2
推荐指数
1
解决办法
296
查看次数

在C++中推断lambda的模板类型

我必须上课:

template<typename T>
class SafeCallback
{
public:
    typedef std::function<T> FunctionType;
    SafeCallback(std::shared_ptr<bool> is_valid, FunctionType callback)
        : is_valid_(is_valid), callback_(callback)
    {
    }

    template <class ...Arg>
    void operator()(Arg&&... parameters)
    {
        if ((*is_valid_) == true)
        {
            callback_(std::forward<Arg>(parameters)...);
        }
    }

private:
    std::shared_ptr<bool> is_valid_;
    FunctionType callback_;
};
Run Code Online (Sandbox Code Playgroud)

要使用lambda作为回调来构造这样的对象,我可以这样做:

SafeCallback<void(int)>(guard, [] (int value) { /* Do sthing */ });
Run Code Online (Sandbox Code Playgroud)

但我想,C++应该有一种方法来推断SafeCallback使用工厂方法的类型参数.如果我创建这样的方法:

template<typename T>
SafeCallback<T> makeSafe(std::shared_ptr<bool> is_valid, std::function<T> callback)
{
    return SafeCallback<T>(is_valid, callback);
}
Run Code Online (Sandbox Code Playgroud)

但这不适用于lambdas,只有我通过了std::function.有任何想法吗?

c++ lambda templates generic-programming c++11

2
推荐指数
1
解决办法
751
查看次数

是最新标准中的命名模板参数还是在当代编译器中实现?

命名模板参数可以说是C++中非常重要的特性.即,给定具有许多具有默认参数的模板参数的类模板,此功能将允许用户为这些参数的任意子集提供参数.Vandervoorde和Josuttis撰写的"C++模板:完整指南"将整个第16.1节用于实现命名模板参数的效果.

同一本书的第13.9节命名模板参数列为可能添加到该语言的功能之一.鉴于此估计可以追溯到12年前,并且该功能具有很大的实用性,我想知道:将命名模板参数设置为最新标准和/或在现代编译器中实现吗?

如果第一个问题的答案是否定的,那么我想了解我所缺少的内容,即:为什么对此功能的需求并不像我认为的那么糟糕?

c++ templates generic-programming policy-based-design c++14

2
推荐指数
1
解决办法
99
查看次数

我如何做泛型泛型?

import java.util.LinkedList;
class GenericInseption{
  public static void main(String[] args){
    LinkedList<LinkedList<Dad>> listOfLists = new LinkedList<>();
    LinkedList<Dad> list = new LinkedList<>();
    listOfLists.add(list);
    test(listOfLists);//error
  }
  private static void test(LinkedList<LinkedList<? extends Person>> listOfLists){
    for(LinkedList<? extends Person> list : listOfLists){
      for(Person person : list){
        //peform operation on person objects
      }
    }
  }
}
class Person{}
class Dad extends Person{}
Run Code Online (Sandbox Code Playgroud)

错误

GenericInseption.java:7: error: method test in class GenericInseption cannot be applied to given types;
    test(listOfLists);//error
    ^
  required: LinkedList<LinkedList<? extends Person>>
  found: LinkedList<LinkedList<Dad>>
  reason: argument mismatch; LinkedList<LinkedList<Dad>> …
Run Code Online (Sandbox Code Playgroud)

java generics generic-list generic-programming

2
推荐指数
1
解决办法
39
查看次数

如何创建泛型函数,它将返回c ++中任何级别指针的值?

我想要一个函数,它将返回指针的值,无论它指向什么级别的指针.喜欢它可能是单个或双指针或三指针或更多,但该函数应返回该值.

例:

#include <iostream>
using namespace std;

template <class T>
T func(T arg){
      // what to do here or there is some other way to do this?????
}

int main() {
    int *p, **pp, ***ppp;
    p = new int(5);
    pp = &p;
    ppp = &pp;

    cout << func(p);    // should print 5
    cout << func(pp);   // should print 5
    cout << func(ppp);  // should print 5
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以,现在我想在一个函数中传递这个p,pp,ppp,它应该打印或返回值'5'.

c++ templates pointers generic-programming

2
推荐指数
1
解决办法
90
查看次数

如何根据C++中可变大小的模板模板列表获取元组?

我创建了一个模板类,它接受两个普通的模板参数(如int或double),并从中派生了几个其他类:

template <typename A, typename B>
class IClassBase {...}

template <typename B>
class Derived1Class : public IClassBase<std::string, B> {...}

template <typename B>
class Derived2Class : public IClassBase<std::string, B> {...}
Run Code Online (Sandbox Code Playgroud)

我需要设计一个结构,允许编译器根据模板类型及其参数列表构建一个std :: tuple(上面代码片段中的B类型).

所以给出下面的列表

Derived1Class<int>, Derived1Class<double>, Derived2Class<bool>, Derived2Class<std::string>
Run Code Online (Sandbox Code Playgroud)

编译器应该推断出以下元组:

std::tuple<int, double, bool, std::string>
Run Code Online (Sandbox Code Playgroud)

这是否可能,如果是这样,如何在C++中完成?

提前致谢)

c++ stl tuples generic-programming variadic-templates

2
推荐指数
1
解决办法
246
查看次数