我正在编写一个import pandas as pd
...
# Function for creating pandas dataframes from SQL-statements
def sqlToFrame(sql):
db = ibm_db.connect(connection_string, "", "")
con = ibm_db_dbi.Connection(db)
return pd.read_sql(sql, con, params = (u'Å',))
df = sqlToFrame("SELECT * FROM DATA_CONFIG WHERE TAG_NAME = ?")
类,表示可能存在或不存在的值。 Option
函数用于获取if_opt
和一个函数,该函数将在Option
中保存的值上调用,但仅在值存在时才会调用。
Option
我注意到如果我这样使用它会有效:
template <class T>
class Option {
private:
std::shared_ptr<T> m_value;
public:
explicit operator bool()const noexcept
{
return (bool)m_value;
}
Option() = default;
explicit Option(T value)
{
m_value = std::make_shared<T>(value);
}
template <class U>
friend void if_opt(Option<U>&, std::function<void(U&)>);
};
template <class T>
void if_opt(Option<T>& opt, std::function<void(T&)> f)
{
if (opt) f(*opt.m_value);
};
但是我希望能够将lambda表达式直接放在调用中,但是当我这样做时:
Option<int> none;
Option<int> some(10);
function<void(int&)> f1 = [](int& none)
{
cout << "This should never be reached" << endl;
};
function<void(int&)> f2 = [](int& some)
{
cout << "The value of some is: " << some << endl;
};
if_opt(none, f1);
if_opt(some, f2);
我收到错误:
if_opt(none, [](int&)
{
cout << "This should never be reached" << endl;
});
if_opt(some, [](int& some)
{
cout << "The value of some is: " << some << endl;
});
我知道lambda表达式的类型在标准中是未定义的,并且它只需要分配给error: no matching function for call to 'if_opt(Option<int>&, main()::<lambda(int&)>)'
,所以这种方法是有意义的,但有没有办法让我可以得到lambda参数隐式转换为std::function<R(T)>
,以便我可以按照我尝试的方式调用std::function<void(T&)>
中的lambda?
答案 0 :(得分:2)
std::function<Sig>
是一种类型擦除工具。它会删除(几乎)关于它存储的值的所有内容,可以使用Sig
调用它。
模板参数推导采用传入类型并推导出应该使用的类型,然后生成并(通常)调用模板函数。
这些几乎是彼此的反转。对类型擦除模板进行演绎是代码嗅觉,几乎总是一个坏主意。
这是你的基本设计错误。
有许多方法可以修复您的代码。
首先,if_opt
不应该是模板。
friend void if_opt(Option<T>& opt, std::function<void(T&)> f){
if (opt) f(*opt.m_value);
}
这创造了我称之为Koenig的朋友。您必须内联定义主体。实际上,U
类型毫无意义,甚至可能在某些情况下导致错误。
但这里的类型擦除也毫无意义。修复返回模板,但现在有充分的理由。
template<class F>
friend void if_opt(Option<T>& opt, F&& f){
if (opt) f(*opt.m_value);
}
这是一个更好的设计。
你可以去投资SFINAE重载解析代码,但我不会打扰。
template<class F,
std::conditional_t<true, bool,std::result_of_t<F&(T&)>> = true
>
friend void if_opt(Option<T>& opt, F&& f){
if (opt) f(*opt.m_value);
}
以上是模糊的,并且与上面的优势相比具有最小的边际优势。