我试图理解为什么我们需要标准示例代码的所有部分:
a `par` b `pseq` a+b
以下为什么不够?
a `par` b `par` a+b
上述表达式似乎很描述:尝试同时评估a和b并行,并返回结果a+b.仅仅是效率的原因:第二个版本会引发两次而不是一次?
以下,更简洁的版本怎么样?
a `par` a+b
为什么我们需要确保在原始标准代码b之前进行评估a+b?
声明如下的内容
void foo(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }
有意义吗?调用者如何能够区分它们?我试过了
foo(9);  // Compiler complains ambiguous call.
int x = 9;
foo(x);  // Also ambiguous.
const int &y = x;
foo(y);  // Also ambiguous.
假设我有一个[acme]对象流,我想通过API公开.我有两个选择,回调和迭代器.
// API #1
// This function takes a user-defined callback 
// and invokes it for each object in the stream.
template<typename CallbackFunctor>
void ProcessAcmeStream(CallbackFunctor &callback);
// API #2
// Provides the iterator class AcmeStreamIterator.
AcmeStreamIterator my_stream_begin = AcmeStreamIterator::begin();
AcmeStreamIterator my_stream_end   = AcmeStreamIterator::end();
API#1从用户手中获取程序的控制流,并且在整个流被消耗之前不会返回(暂时忘记异常).
API#2保留用户手中的控制流,允许用户自己前进流.
API#1感觉更高级别,允许用户立即跳转到业务逻辑(回调函子).另一方面,API#2感觉更灵活,允许用户更低级别的控制.
从设计的角度来看,我应该选择哪一个?我还没有看到更多的利弊吗?未来有哪些支持/维护问题?
在阅读维基百科关于decltype的页面时,我很好奇这个陈述,
其[decltype]的主要用途是在通用编程中,通常很难甚至不可能命名依赖于模板参数的类型.
虽然我可以理解该语句的难点部分,但是需要命名一个无法在C++ 03下命名的类型的示例是什么?
编辑:我的观点是,因为C++中的所有内容都有类型声明.为什么会出现无法命名类型的情况?此外,是不是设计用于产生类型信息的特质类?特质课可以替代decltype吗?
假设我们要应用一系列的变换,int f1(int),int f2(int),int f3(int),对对象的列表.一种天真的方式
SourceContainer source;
TempContainer1 temp1;
transform(source.begin(), source.end(), back_inserter(temp1), f1);
TempContainer2 temp2;
transform(temp1.begin(), temp1.end(), back_inserter(temp2), f2);
TargetContainer target;
transform(temp2.begin(), temp2.end(), back_inserter(target), f3);
这第一个解决方案是因为有多余的空间要求不是最优的temp1和temp2.所以,让我们更聪明一点:
int f123(int n) { return f3(f2(f1(n))); }
...
SourceContainer source;
TargetContainer target;
transform(source.begin(), source.end(), back_inserter(target), f123);
这第二个解决方案是要好得多,因为不仅是代码简单,但更重要的是有没有中间的计算空间需求少.
但是,组合f123必须在编译时确定,因此在运行时固定.
如果要在运行时确定合成,我将如何有效地尝试这样做?例如,如果这个码是在一个RPC服务和实际组成-其可以是任何的子集的任何置换f1,f2和f3--is基于来自RPC调用的参数.
作为我在C++标准ANSI ISO IEC 14882 2003上阅读厕所的一部分,我遇到了以下内容:
14.3.1.2:本地类型,没有链接的类型,未命名的类型或从这些类型中的任何类型复合的类型不得用作模板类型参数的模板参数.
虽然我得到的是本地类型和复合类型,但什么是未命名的类型?如果一个类型未命名,你怎么能尝试在模板中使用它,这促使标准口头排除它?
假设我有课程
class Inner {
  public:
    void doSomething();
};
class Outer {
  public:
    Outer(Inner *inner);  // Dependency injection.
    void callInner();
};
适当的单元测试说我应该进行测试Inner.然后,我应该测试Outer使用不是真实的Inner,而是一个,MockInner所以我将对添加的功能进行单元测试,Outer而不是完整的堆栈Outer/ Inner.
要做到这一点,Googletest似乎建议Inner变成一个纯粹的抽象类(接口),如下所示:
// Introduced merely for the sake of unit-testing.
struct InnerInterface {
  void doSomething() = 0;
};
// Used in production.
class Inner : public InnerInterface {
  public:
    /* override */ void doSomething();
};
// Used in unit-tests.
class MockInner : …假设我决定用C或任何其他过程编程语言编写大型应用程序.它具有调用依赖项的函数,如下所示:
A
|
+-------------+
|             |
B1            B2
|             |
+------+      +------+
|      |      |      |
C11    C12    C21    C22
显然,单元测试叶片功能,C11,C12,C21和C22非常简单:设置输入,调用功能,断言输出.
但是,为B1,B2和A进行良好的单元测试的正确策略是什么?
将依赖注入建议B1(和B2也)可以作为随后宣布?
// Declare B1 with dependency injection for invoking C11 and C12.
int B1(int input, int (*c11)(int), int(*c12)(int));
但是,如果我有多层呼叫,那么这种策略似乎不具备可扩展性.想象一下声明的A样子:
int A(int input, int (*b1)(int, int (*)(int), int(*)(int)), 
                 int(*b2)(int, int (*)(int), int(*)(int)),
                 int (*c11)(int),
                 int (*c12)(int),
                 int (*c21)(int),
                 int (*c22)(int));
呸!一定有更好的方法.
有时,我觉得DI和其他旨在促进模块化和易于维护的类似模式实际上会妨碍代码清晰度,并使简单编码变成无意义的抽象和复杂的间接变得复杂.
C中的大型软件项目(如Perl和Ruby)如何处理单元测试?
假设我有两个函数DoTaskA和DoTaskB-both能够抛出TaskException相应的"回滚"函数UndoTaskA和UndoTaskB.什么是最好的模式,以便成功或两者都失败?
我现在最好的是
bool is_task_a_done = false,
     is_task_b_done = false;
try {
    DoTaskA();
    is_task_a_done = true;
    DoTaskB();
    is_task_b_done = true;
} catch (TaskException &e) {
    // Before rethrowing, undo any partial work.
    if (is_task_b_done) {
        UndoTaskB();
    }
    if (is_task_a_done) {
        UndoTaskA();
    }
    throw;
}
我知道这is_task_b_done是不必要的,但是如果我们稍后添加第三个或第四个任务,则可能显示代码对称性.
由于辅助布尔变量,不喜欢这段代码.也许新的C++ 11中有一些我不知道的东西,可以更好地编写代码吗?
我可以通过封装,依赖注入,最少知识原则,你不需要它来掌握"做一件事"的部分; 但我怎么理解第二部分"做得好"?
给出的一个例子是完整性的概念,在同一篇YAGNI文章中给出:
例如,在允许添加项目,删除项目或修改项目的特征中,可以使用完整性来推荐"重命名项目".
但是,我发现这样的推理很容易被滥用到特征蠕变中,从而违反了"做一件事"的部分.
因此,看到相当一个特征属于"做得好"类别(因此,将其包含在函数/类/程序中)或其他"做一件事"类别(因此,排除它)的试金石是什么? ?
第一部分,"做一件事",最好通过UNIX的ls命令来理解,因为它包含了过多的标志来格式化它的输出,这些标志本应完全委托给另一个外部程序.但我没有一个很好的例子来看第二部分"做得好".
什么是一个很好的例子,删除任何进一步的功能将使它不"做得好"?
c++ ×7
templates ×2
types ×2
c++11 ×1
callback ×1
decltype ×1
googletest ×1
haskell ×1
iterator ×1
mocking ×1
overloading ×1
pipeline ×1
single-responsibility-principle ×1
standards ×1
unit-testing ×1
yagni ×1