我刚刚学习了对象初始化器,并想知道什么时候使用它们的最佳实践.
这是我读到的关于它们的内容:http://msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx 它清楚地表明它们是创建匿名类型所必需的,但我想知道我是否应该在所有其他情况下,尝试将它们更喜欢正常的构造函数.
好的,这有点复杂所以请耐心等待.:)
class A {};
class DA : public A {};
class DDA : public DA {};
Run Code Online (Sandbox Code Playgroud)
void f(A x) {
std::cout << "f A" << std::endl;
}
void f(DA x) {
std::cout << "f DA" << std::endl;
}
void f(DDA x) {
std::cout << "f DDA" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
现在我们想要添加另一个以不同方式处理DA的函数.
void g(A t) {
std::cout << "generic treatment of A" << std::endl;
std::cout << "called from g: ";
f(t);
}
void g(DA t) {
std::cout << "special …Run Code Online (Sandbox Code Playgroud) 我基本上尝试与std :: enable_if:参数vs模板参数一样,但我无法编译我的代码.
我有一个简单的第一个版本,在参数中有std :: enable_if,并且工作正常:
#include <iostream>
#include <type_traits>
template <typename T>
void foo(T t, typename std::enable_if< std::is_same<T, int>::value >::type* = 0) {
std::cout << "int" << std::endl;
}
template <typename T>
void foo(T t, typename std::enable_if< !std::is_same<T, int>::value >::type* = 0) {
std::cout << "not int" << std::endl;
}
int main(int argc, char* argv[])
{
foo(10);
foo(10.1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但我认为如果模板的东西在一个地方并且想要函数参数中的enable_if可能会更简洁.
现在,如果我只是移动enable_if部分,我会得到以下内容:
#pragma warning(1 : 4519)
#include <iostream>
#include <type_traits>
template <typename T, typename std::enable_if< std::is_same<T, …Run Code Online (Sandbox Code Playgroud) 我假设函数已经有一个返回值,因此无法添加.
我想出来解决这个问题的方法是添加额外的指针参数,默认为nullptr.
之前:
bool fun(double a, std::vector<std::randomexample> const & b)
Run Code Online (Sandbox Code Playgroud)
后:
bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput = nullptr)
Run Code Online (Sandbox Code Playgroud)
并像这样使用它
if(extraoutput)
*extraoutput = whatever;
Run Code Online (Sandbox Code Playgroud)
但这正是我提出的.我想知道是否有更好的方法来做到这一点.请注意,函数中已经存在"无论什么".
我想在我的代码中清楚地区分3D和2D点.显而易见的解决方案是拥有单独的类.
另一方面,从z = 0到2D点的3D点的转换非常常见.因此,我想使用一个公共基类,这样我就可以在内存中进行这些转换.为了明确区分类型,我想禁止隐式转换为该基类.那可行吗?
或者是否可能有不同的方法来创建具有类似功能的不同类型?
它们是否跨不同的目标文件工作?它们是否跨不同的DLL工作?
我知道这取决于编译器.我很好奇是否有任何编译器和优化设置可以使这项工作.
我仍在试图弄清楚模板.我已经阅读了有关专业化规则的内容,并且不明白这里发生了什么.
我在templates.h中定义了以下内容:
#include <iostream>
template <typename foo>
void f(foo p)
{
std::cout << "one" << std::endl;
}
template <typename bar>
void f(int p)
{
std::cout << "two" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我包括这个,并在我的主要像这样称呼它
f(1);
f("x");
Run Code Online (Sandbox Code Playgroud)
我明白了
one
one
Run Code Online (Sandbox Code Playgroud)
现在的问题是,为什么第一个更具体而不是第二个用于整数?我觉得它至少应该是模棱两可的,根本不起作用.
今天早些时候,我在工作中对某些代码运行代码分析时遇到了CA1063 。
我有两个问题:
为什么以下代码不会导致 CA1063,即使它明显违反了某些要求(例如 Dispose 被覆盖)
代码的实际问题是什么,导致了由密封的 Dispose() 和终结器等调用的虚拟 Dispose(bool) 的复杂方案。
Run Code Online (Sandbox Code Playgroud)using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Foobar : IDisposable { public Foobar() { Console.Out.WriteLine("Constructor of Foobar"); } public virtual void Dispose() { Console.Out.WriteLine("Dispose of Foobar"); GC.SuppressFinalize(this); } ~Foobar() { Console.Out.WriteLine("Finalizer of Foobar"); } } class Derived : Foobar { public Derived() { Console.Out.WriteLine("Constructor of Derived"); } public override void Dispose() { Console.Out.WriteLine("Dispose of Derived"); GC.SuppressFinalize(this); base.Dispose(); } ~Derived() { Console.Out.WriteLine("Finalizer of …
Visual Studio具有这样一个简洁的功能,即每当出现异常时弹出一个消息框,允许您打破它并检查程序状态,即使理论上稍后捕获异常也是如此.
我想使用这样的东西用于记录目的.自动记录正在引发的每个异常.这对于引发异常但在库代码中被捕获的情况尤其有用,即使它不应该被引用.
因此,问题是:可以这样做,如果是,怎么做?
编辑:不确定这是否足够明显:我不想编写代码来捕获,记录和重新抛出所有异常.
如何在C++中执行以下操作:
template <typename T>
void Foo(T t)
{
...
call Bar(true) if T is of some specific type U or V
call Bar(false) otherwise
...
}
void Bar(bool b)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我可以添加一个冗余的模板参数,但它会是多余的.
我也可以尝试使Bar成为模板函数,并将其专门用于U和V,但这不是我的代码,问题可能只会传播.
我可以创建一个CallBar除了调用Bar(false)和专门调用Bar(true)U和V之外什么都不做的函数.但是这个例子实际上有点过于简单了.布尔值在FooLogger中的多个位置使用,Bar有时甚至在?:conditionals 中调用函数(因此有多个s).
这里最好的事情是什么?
我实际上要做的是编写一个函数,允许我更改DataGridView中的选择,我想编写一个函数并将其用于行和列.这是一个简单的示例,取消选择所有内容并选择新的行或列:
private void SelectNew<T>(T collection, int index) where T : IList
{
ClearSelection();
collection[index].Selected = true;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这不起作用,因为它无法派生,.Selected()因为这是非通用的IList.
运用
where T : IList<DataGridViewBand>
Run Code Online (Sandbox Code Playgroud)
会很好但是因为DataGridViewRowCollection(和-Column-)只是从IList派生而来,所以不起作用.
在C++中,我可能会使用traits idiom.有没有办法在C#中做到这一点,还是有更惯用的方式?
c++ ×8
c# ×4
templates ×3
.net ×1
class ×1
constructor ×1
copy-elision ×1
exception ×1
finalizer ×1
function ×1
generics ×1
idisposable ×1
logging ×1
overloading ×1
parameters ×1
rvo ×1