我正在尝试根据the boost hana manual中的any
类型切换示例编写任意值切换。
我之前已经成功完成了这项工作,但现在似乎无法完成。
我真的想弄清楚我的解决方案到底出了什么问题,所以不用多说了:
struct default_val{
constexpr bool operator ==(const auto&) const noexcept{ return false; }
constexpr bool operator !=(const auto&) const noexcept{ return true; }
constexpr bool operator ==(default_val) const noexcept{ return true; }
constexpr bool operator !=(default_val) const noexcept{ return false; }
};
template<typename Fn>
auto default_(Fn fn){
return hana::make_pair(default_val{}, fn);
}
template<typename Val, typename Fn>
auto case_(Val val, Fn fn){
return hana::make_pair(val, fn);
}
template<typename Val, typename Default>
decltype(auto) process(Val&&, Default &&def){
return hana::second(std::forward<Default>(def))();
}
template<typename Val, typename Default, typename Case, typename ... Rest>
decltype(auto) process(Val &&val, Default &&def, Case &&cas, Rest &&... rest){
if(std::forward<Val>(val) == hana::first(std::forward<Case>(cas)))
return hana::second(std::forward<Case>(cas))();
else
return process(std::forward<Val>(val), std::forward<Default>(def), std::forward<Rest>(rest)...);
}
template<typename Val>
auto switch_(Val val){
return [val](auto ... cases){
auto cases_ = hana::make_tuple(cases...);
auto default_ = hana::find_if(cases_, [](const auto &c){
return
hana::type_c<default_val> ==
hana::type_c<std::decay_t<decltype(hana::first(c))>>;
});
static_assert(default_ != hana::nothing);
auto rest_ = hana::filter(cases_, [](const auto &c){
return
hana::type_c<default_val> !=
hana::type_c<std::decay_t<decltype(hana::first(c))>>;
});
return hana::unpack(rest_, [&](const auto &... rest){
return process(val, default_, rest...);
});
}
}
这应该像any
示例一样使用,但值为:
#include "myswitch.hpp"
int main(){
std::string input;
std::cin >> input;
switch_(input)(
case_("yowza", []{ std::cout << "where's the enthusiasm?\n"; }),
case_("Yowza", []{ std::cout << "wat2hek\n"; }),
case_("YOWZA!", []{ std::cout << "HooRah!\n"; }),
default_([]{ std::cout << "Hello, World!\n"; })
);
}
但是,在hana::find_if_t::operator()(Xs&&, Pred&&)
中分配auto
时,在扣除default_
之前,我对switch_
使用using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
SqlConnection con, con1;
SqlCommand cmd, cmd1;
DataSet ds, ds1;
private int _x;
public int X
{
get { return _x; }
set { _x = value; }
}
public _Default()
{
con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["GuitarItemsDBConnectionString2"].ToString();
cmd = new SqlCommand();
ds = new DataSet();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
bindgridviewguitaritems();
}
}
public void getRowNumber(string brand, string model)
{
string query = string.Format("SELECT Rn FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY id) AS Rn FROM guitarItems WHERE brand LIKE '{0}') x WHERE x.Model LIKE '{1}'",brand,model);
con.Open();
cmd.Connection = con;
cmd.CommandText = query;
Int32 count = (Int32)cmd.ExecuteScalar(); //<----Here is the error
X = count;
con.Close();
}
//Start of Gridview Code for Guitar Items
private void bindgridviewguitaritems()
{
con.Open();
cmd.CommandText = "SELECT * FROM [guitarItems]";
cmd.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
con.Close();
GridView1.DataBind();
}
protected void GridViewBtn1_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
GridViewRow gridrow = btn.NamingContainer as GridViewRow;
int id = Convert.ToInt32(GridView1.DataKeys[gridrow.RowIndex].Value.ToString());
string name = GridView1.Rows[gridrow.RowIndex].Cells[3].Text;
string model = GridView1.Rows[gridrow.RowIndex].Cells[4].Text;
getRowNumber(name,model);
Label1.Text = X.ToString();
Label2.Text = name;
Label3.Text = model;
con.Open();
cmd.CommandText = "DELETE FROM [guitarItems] WHERE id=" + id;
cmd.Connection = con;
int a = cmd.ExecuteNonQuery();
con.Close();
if (a > 0)
{
bindgridviewguitaritems();
}
System.IO.File.Delete(@"C:\Users\User1\Documents\Visual Studio 2015\WebSites\MusicStore\Pages\GuitarItems" + name + "Details" + id + ".aspx");
System.IO.File.Delete(@"C:\Users\User1\Documents\Visual Studio 2015\WebSites\MusicStore\Pages\GuitarItems" + name + "Details" + id + ".aspx.cs");
}
//End of Gridview Code for Guitar Items
提出了一个长篇大论且含糊不清的错误。
有人能指出我在正确的方向吗?
答案 0 :(得分:3)
根据Boost.Hana的谓词手册(强调我的):
一个名为谓词(k)的函数,其中k是结构的一个关键字,并返回k是否是被搜索元素的关键字。在库的当前版本中,谓词必须返回一个IntegralConstant,其中包含一个可以转换为bool的值。
这是hana::find_if
和hana::filter
使用的谓词所必需的。
对于您的default_val
类型,可以将实施更改为:
struct default_val {
template <typename T>
constexpr auto operator ==(const T&) const noexcept{ return hana::false_c; }
template <typename T>
constexpr auto operator !=(const T&) const noexcept{ return hana::true_c; }
constexpr auto operator ==(default_val) const noexcept{ return hana::true_c; }
constexpr auto operator !=(default_val) const noexcept{ return hana::false_c; }
};
我使用Clang 3.9运行您的代码,并且通过以下附加调整工作正常,可以打开default_
可选值中的值。
return hana::unpack(rest_, [&](const auto &... rest){
return process(val, *default_, rest...);
// ^ Note the added dereference operator here