我知道基类模板的成员名称隐藏在派生类的范围内,因此必须使用this->foo或访问Base<T>::foo.但是,我记得C++还允许您使用using关键字,它可以在派生类函数中派上用场,该函数经常访问基类变量.所以,为了避免在this->任何地方混乱功能,我想使用using关键字.
我知道我以前做过这个,但无论出于什么原因我现在都无法上班.我可能只是做了一些愚蠢的事情,但以下代码无法编译:
template <class T>
struct Base
{
int x;
};
template <class T>
struct Derived : public Base<T>
{
void dosomething()
{
using Base<T>::x; // gives compiler error
x = 0;
}
};
int main()
{
Derived<int> d;
}
Run Code Online (Sandbox Code Playgroud)
错误(使用GCC 4.3)是: error: ‘Base<T>’ is not a namespace
为什么这不起作用?
我很高兴继承了一个非常复杂的SharePoint项目.
显然,原始开发人员是可重用代码的忠实粉丝(30%的代码在不使用任何库的情况下在20个项目中重复使用 - 猜怎么样?).
我经常会发现他的代码调用一些Common.OpenWeb方法来检索SPWeb操作SharePoint内容的对象.这个函数的大部分内容看起来完全相同:
public SPWeb OpenWeb()
{
String strSiteUrl = ConfigurationManager.AppSettings["SiteUrl"].ToString();
SPSite site = null;
SPWeb web = null;
try
{
using (site = new SPSite(strSiteUrl))
{
using (web = site.OpenWeb())
{
return web;
}
}
}
catch (Exception ex)
{
LogEvent("Error occured in OpenWeb : " + ex.Message, EventLogEntryType.Error);
}
return web;
}
Run Code Online (Sandbox Code Playgroud)
而现在我真的很担心.
为什么这在生产中有效?这个方法总是返回一个被处理的对象,对吧?
它到底有多不稳定?
更新:
此方法以下列方式使用:
oWeb = objCommon.OpenWeb();
SPList list = oWeb.Lists["List name"];
SPListItem itemToAdd = list.Items.Add();
itemToAdd["Some field"] = …Run Code Online (Sandbox Code Playgroud) 如果我有这个方法:
public StreamReader GetResourceStream(string filename)
{
using (Stream stream = this.GetType().Assembly.GetManifestResourceStream(filename))
using (StreamReader sr = new StreamReader(stream))
{
return sr;
}
}
Run Code Online (Sandbox Code Playgroud)
当我打电话给它时,我应该这样称呼它
StreamReader resource = GetResourceStream("blah.xml");
Run Code Online (Sandbox Code Playgroud)
或者这样:
using (StreamReader resource = GetResourceStream("blah.xml"))
{
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)
如果是第二种方式,这是否意味着该using (StreamReader sr = new StreamReader(stream))线路没有使用using声明产生任何差异?
我知道下面using C1::fn;将把C1中声明的fn(...)函数带到C2,但我想知道这样using设计的最佳实践是什么?
如果fn()函数没有使用C1状态,我应该声明一个帮助类是更好的方法吗?如果fn函数正在使用C1状态,那么using打破封装?
如果您甚至可以在C++ 11中提及一些使用案例,我感谢您.就像使用using Base::Base;构造函数而不是从派生成员初始化程序调用它?
class C1
{
//...
public:
int fn(int j) { ... }
double fn(double w) { ... }
void fn(const char * s) { ... }
};
class C2 : public C1
{
//...
public:
//...
using C1::fn;
double fn(double) { ... };
};
Run Code Online (Sandbox Code Playgroud) 这是以下代码健康吗?或者我不需要使用using关键字作为SqlDataAdapter将处理关闭连接?
public static DataSet Fetch(string sp, SqlParameter [] prm)
{
using (SqlConnection con = new SqlConnection(ConStr))
{
using (SqlCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = sp;
cmd.Parameters.AddRange(prm);
using (SqlDataAdapter dta = new SqlDataAdapter(cmd))
{
DataSet dst = new DataSet();
dta.Fill(dst);
return dst;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
@MarkGravell我在这里需要一个建议,我真的很想使用DataReader,但我一直在寻找使用该using关键字以确保关闭连接.在哪里DataReader我们不能使用它,因为如果我们想要返回DataReader某个方法,它将关闭连接.所以你认为以下技术DataReader和using关键字一样好:
public static SqlDataReader Fetch(string sp, SqlParameter [] prm)
{
SqlCommand cmd = new SqlConnection(ConStr).CreateCommand(); …Run Code Online (Sandbox Code Playgroud) 我有一个小类,内部使用几个STL列表
template<class T>
class MC_base {
using OBJ_LIST = std::list<T>;
using OBJ_VAL = typename OBJ_LIST::value_type;
using OBJ_ITR = typename OBJ_LIST::iterator;
using OBJ_CITR = typename OBJ_LIST::const_iterator;
OBJ_LIST A,B,C;
...
};
Run Code Online (Sandbox Code Playgroud)
使用这些using语句,如果我在类定义中编写一个迭代器,它看起来很漂亮:
OBJ_ITR begin() { return A.begin(); };
OBJ_ITR end() { return A.end(); };
OBJ_CITR begin() const { return A.begin(); };
OBJ_CITR end() const { return A.end(); };
Run Code Online (Sandbox Code Playgroud)
在类定义中再次编写新函数很容易,因为我可以OBJ_XXXX在需要时简单地使用名称.此外,如果我决定std::vector稍后更改容器类型(比方说),我只需更改一行,只要我的新容器支持所有相同的操作,一切都应该是无缝的.
但是,当我想在类定义之外定义一个新的类函数时,这是有问题的
template<class T>
OBJ_ITR MC_base<T>::foo(OBJ_ITR x) { ... }
Run Code Online (Sandbox Code Playgroud)
我不确定如何"带出"using语句,以便它们与模板一起正确工作,而不是为每个过于冗长的函数定义它们.另外,我不想用using语句污染命名空间.
有没有正确的方法using与模板一起使用?
我的问题可能是愚蠢的,或者根本不是一个问题,但在这里......
我在我的ASP.net MVC项目中执行了一些数据库操作,我每次创建两个对象,SqlConnection和SqlCommand.
我在下面展示了一个例子
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand("sRegisterUser", connection))
{
Run Code Online (Sandbox Code Playgroud)
我在不同方法的一个类中进行所有这些不同的操作.
我的问题是如何每次都减少这些对象的创建?我如何在全球范围内创建它们
PS:sRegisterUser是一个存储过程,就像明智的其他方法一样,使用不同的过程,它们将不同的值作为参数.
请帮帮我.
在此先感谢您的帮助.
我正在写一些C#重数学.许多行依次使用大量的abs(),min(),max(),sqrt()等.使用C#是普通的常规方法,我必须在每个函数前加上"Math".例如
double x = Math.Min(1+Math.Sqrt(A+Math.Max(B1,B2)),
Math.Min(Math.Cos(Z1),Math.Cos(Z2)));
Run Code Online (Sandbox Code Playgroud)
我宁愿像C一样编写代码:
double x = min(1+sqrt(A+max(B1,B2)), min(cos(Z1), cos(Z2)));
Run Code Online (Sandbox Code Playgroud)
这更容易阅读,对科学家和工程师来说看起来更自然.正常的C#方式隐藏了"数学"迷雾中的好位.
C#中有没有办法做到这一点?
经过一些谷歌搜索后,我找到了一个让我尝试的例子
using min = Math.Min;
...
double x = min(a,b);
Run Code Online (Sandbox Code Playgroud)
但是"using"语句产生了一个错误,"System.Math.Min(十进制,十进制)是一个方法但是像一个类型一样使用"但是这看起来像是一个很好的解决方案.(无论如何,'小数'是什么?)
为什么委员会决定不与模板typedef一起批准using?
template <class T>
using my_vector = std::vector<T>;
Run Code Online (Sandbox Code Playgroud)
是合法的.
但
template <class T>
typedef std::vector<T> my_vector<T>;
Run Code Online (Sandbox Code Playgroud)
是非法的?
UPD.问题为什么C++ 11没有模板typedef?没有回答.
我想做类似下面的事情(在c ++ 11,c ++ 14;而不是c ++ 17):
template <class T>
using partner = void;
template<>
using partner<A> = X;
template<>
using partner<B> = Y;
template<>
using partner<C> = Z;
Run Code Online (Sandbox Code Playgroud)
但我收到编译错误---
错误:'使用'之前的预期unqualified-id
---关于第一个模板专业化.
这样的事情可能吗?(我已经知道我可以使用带有using语句的模板化类.我希望直接使用using没有类包装器的语句,因为它更简单,更优雅.如果有另一个简单,优雅的解决方案,请分享!)