标签: metaprogramming

动态生成方法名称的前缀

假设我们有一堆带有典型前缀的方法.

def pref_foo
  # code
end

def pref_bar
  # code
end
Run Code Online (Sandbox Code Playgroud)

我想学习如何自动将这些前缀添加到我的方法名称中(就像在Rails中完成它一样Model.find_by_smth).

换句话说,我想创建一些范围pref_,它采用方法和prepends pref_到它们的名字,所以我的方法foo变得可用pref_foo.


module Bar
  # definition of some wrapper `pref_`
end

class Foo
  include Bar

  <some wrapper from Bar> do
    def foo
      puts 'What does a computer scientist wear on Halloween?'
    end

    def bar
      puts 'A bit-mask.'
    end
  end
end

foo = Foo.new

foo.pref_foo # => "What does a computer scientist wear on Halloween?"
foo.pref_bar # => "A bit-mask."
Run Code Online (Sandbox Code Playgroud)

ruby dsl metaprogramming

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

如何使用函数args进行元编程?

这是我第二天学习和实验朱莉娅.虽然我仔细阅读了有关元编程的文献记录(但可能不够仔细)和几个类似的线程.我仍然无法弄清楚如何在函数中使用它.我试着让以下函数更灵活地模拟一些数据:

using Distributions
function gendata(N,NLATENT,NITEMS)
  latent = repeat(rand(Normal(6,2),N,NLATENT), inner=(1,NITEMS))
  errors = rand(Normal(0,1),N,NLATENT*NITEMS)
  x = latent+errors
end
Run Code Online (Sandbox Code Playgroud)

通过做这个:

using Distributions
function gendata(N,NLATENT,NITEMS,LATENT_DIST="Normal(0,1)",ERRORS_DIST="Normal(0,1)")
  to_eval_latent = parse("latent = repeat(rand($LATENT_DIST,N,NLATENT), inner=(1,NITEMS))")
  eval(to_eval_latent)
  to_eval_errors = parse("error = rand($ERRORS_DIST,N,NLATENT*NITEMS)")
  eval(to_eval_errors)
  x = latent+errors
end
Run Code Online (Sandbox Code Playgroud)

但由于eval不适用于本地范围,因此不起作用.我可以做些什么来解决这个问题呢?

最初的功能,似乎并不那么快,我是否在性能方面犯了重大错误?

我真的很喜欢任何推荐.提前致谢.

scope metaprogramming julia

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

编译器如何评估模板函数?

考虑以下可变参数模板函数:

template<typename T, typename... Args>
auto foo(Args... args) -> T[sizeof...(args)]
{
   T t[sizeof...(args)];
   // Maybe do some pack expansion/assignment
   return t;
}
Run Code Online (Sandbox Code Playgroud)

实例化:

// total should be of type int[5];
auto total = foo(1,2,3,4,5);
Run Code Online (Sandbox Code Playgroud)

我知道这不会编译,因为返回类型不可归类,但我不明白为什么它不可推导.

编译器在编译时是否知道这个函数有什么东西,或者被评估的函数部分的顺序是什么,这会阻止类型推导?

我怀疑这是由于函数的调用sizeof...,我认为在运行时进行评估.如果是这样,是否有编译时等效?

c++ templates metaprogramming c++11

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

接受左值,右值和右值ref的C++函数签名

假设我有如下函数:

print_sutff(const std::string stuff) {
    std::cout << stuff;
}
Run Code Online (Sandbox Code Playgroud)

我可以接受:

std::string
std::string&
std::string&&
Run Code Online (Sandbox Code Playgroud)

对函数代码的外观没有任何影响.

但是,可以通过多种方式调用该函数,我希望通过它实现以下行为(或尽可能接近它):

auto pass = "a string";
print_sutff(pass);
Run Code Online (Sandbox Code Playgroud)

在这里用户不能使用&&,我更愿意&优先考虑lvaue

要么:

print_sutff("a string"); 
Run Code Online (Sandbox Code Playgroud)

这里应该调用&&构造函数.

所以我的问题是:

有没有办法让函数接受左值,&和&&?如果是这样,有没有办法根据被调用的上下文优先考虑使用哪一个?

如果没有,有没有办法让函数同时接受&和&&?这意味着使用哪个签名的行为是明确定义的.

c++ templates metaprogramming c++17

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

Julia中的动态函数名称定义可能吗?

我有一个DataFrame结构化parName|region|year,并且访问函数为getData(parName,reg,year)(我使用访问函数,因为我实现了自己的查询逻辑).

基于此unique(df[:parName]),是否可以动态创建一组功能,如par1(region,year)"指向" getData("par1",region,year)

如果是这样,使用哪种方法?

这与这个问题有点相反..它解释了如何动态调用一个函数,而我可以动漫地声明/定义一个函数.

编辑:

我正在使用这种方法,以便在编写多维方程时获得最清晰,最紧凑的语法.我管理(感谢@Liso答案)将其实现为:

for par in unique(dropna(df[:parName]))
   @eval ($(Symbol("$(par)_"))) =   (r,d1,d2="",y=-1,op=sum) -> gd($par,r,d1,d2,y,op)
   @eval ($(Symbol("$(par)!"))) =   (v,r,d1,d2="",y=-1) -> sd(v,$par,r,d1,d2,y)
end
Run Code Online (Sandbox Code Playgroud)

即,我使用的par!()是setData类型的约定,并且par_()是getData类型的等式. 当我能够完成转换f(dim1,dim2) = value成的宏时,f(value,dim1,dim2)我将能够使用类似LaTeX(和类似AMPL)的语法编写我的模型,这种语法非常清楚:

@meq  price!(tp in secProducts, r in fr2) = sum(price_(r,pp,"",y2)*a_(r,pp,tp,y2) for pp in priProducts) + margin_(r,tp,"",y2)
Run Code Online (Sandbox Code Playgroud)

metaprogramming dataframe julia

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

std :: declval <T>(),SFINAE和删除的构造函数

在SF ++中使用C++ 11中的方法检测,我写了这个小小的运行示例:

#include <type_traits>

struct Foo
{
  Foo();// = delete;
  Foo(int);

  void my_method();
};

template <typename T, typename ENABLE = void>
struct Detect_My_Method 
   : std::false_type
{
};

template <typename T>
struct Detect_My_Method<T, decltype(T().my_method())> 
   : std::true_type
{
};

int main()
{
  static_assert(!Detect_My_Method<double>::value, "");
  static_assert(Detect_My_Method<Foo>::value, "");
}
Run Code Online (Sandbox Code Playgroud)

按预期工作.

但是,如果我删除Foo的空构造函数:

struct Foo
{
  Foo() = delete;
  Foo(int);

  void my_method();
};
Run Code Online (Sandbox Code Playgroud)

该示例不再工作,我收到此错误消息:

g++ -std=c++11 declVal.cpp 
declVal.cpp: In function ‘int main()’:
declVal.cpp:33:3: error: static assertion failed
   static_assert(Detect_My_Method<Foo>::value, "");
Run Code Online (Sandbox Code Playgroud)

问题:解释以及如何解决?

c++ metaprogramming sfinae c++11

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

Elixir中的元编程

defmodule BBB do
  IO.puts "BBB"
  defmacro hh do
    IO.puts "hh in BBB"
  end
end

defmodule AAA do
  IO.puts "AAA"
  require BBB
  BBB.hh
end
Run Code Online (Sandbox Code Playgroud)

为什么输出:

BBB
hh in BBB
AAA
Run Code Online (Sandbox Code Playgroud)

我对Elixir的编译过程感到困惑.

metaprogramming elixir

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

元类以及何时/如何调用函数

我正在尝试学习元类如何在python 3中工作.我想知道的是:调用哪些函数,按什么顺序,以及它们的签名和返回.

作为一个例子,我知道__prepare__当带有元类的类用参数实例化metaclass, name_of_subclass, bases并返回表示实例化对象的未来命名空间的字典时,会调用它.

我觉得我理解__prepare__这个过程中的一步.我不这样做,虽然,是__init__,__new____call__.他们的论点是什么?他们回报了什么?他们如何互相称呼,或者一般如何进行?目前,我一直在理解何时__init__被召唤.

这是我一直在讨论的一些代码来回答我的问题:

#!/usr/bin/env python3

class Logged(type):

    @classmethod
    def __prepare__(cls, name, bases):
        print('In meta __prepare__')
        return {}

    def __call__(subclass):
        print('In meta __call__')
        print('Creating {}.'.format(subclass))
        return subclass.__new__(subclass)

    def __new__(subclass, name, superclasses, attributes, **keyword_arguments):
        print('In meta __new__')
        return type.__new__(subclass, name, superclasses, attributes)

    def __init__(subclass, name, superclasses, attributes, **keyword_arguments):
        print('In meta __init__')

class Thing(metaclass = Logged):

    def __new__(this, *arguments, **keyword_arguments):
        print('In sub __new__')
        return super(Thing, …
Run Code Online (Sandbox Code Playgroud)

python metaprogramming metaclass python-3.x

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

循环typedef列表

如果标题有点误导,我很抱歉.

我有一个循环一些数据的函数.每次迭代时此数据的类型都会发生变化.

基本上我有这样的事情:

for(int i = 0; i < limit; i++)
{
  type object;
  object.do_stuff();
}
Run Code Online (Sandbox Code Playgroud)

这里例如在第一次迭代中"type"将是int,在第二次迭代时"type"将是double,等等.

我不能使用varyadic模板,因为我有超过100个元素,据我所知,它对系统非常重要.

我的想法是创建一个"typedef的向量"来循环所有类型的对象.

vector<????> type;
type.push_back(int);
type.push_back(double);
...
for(int i = 0; i < limit; i++)
{
  type[i] object;
  object.do_stuff();
}
Run Code Online (Sandbox Code Playgroud)

我不知道这是否可能.

我看到了类型列表的基础知识,但我不知道是否可以重现循环.

c++ arrays typedef metaprogramming

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

当通过参数启用时,std :: enabled_if如何工作

我试图了解enable_if是如何工作的,除了方案#3之外,我几乎理解了所有内容

https://en.cppreference.com/w/cpp/types/enable_if

template<class T>
void destroy(T* t, 
         typename 
std::enable_if<std::is_trivially_destructible<T>::value>::type* = 0) 
{
    std::cout << "destroying trivially destructible T\n";
}
Run Code Online (Sandbox Code Playgroud)

如果enable_if中的表达式为true,则选择部分模板特化,因此如果选择:

  1. 为什么在enable_if只是条件而没有指示第二个模板参数?
  2. 什么类型的"类型*"呢?无效*?如果是这样,为什么?
  3. 为什么是指针?

c++ templates metaprogramming enable-if

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