标签: rationale

DBNull有什么意义?

在.NET中有一个null引用,它在任何地方用来表示对象引用是空的,然后有DBNull数据库驱动程序(和其他几个)用来表示......几乎相同的东西.当然,这会产生很多混乱,转换例程必须被制作出来,等等.

那么为什么最初的.NET作者决定这样呢?对我来说没有任何意义.他们的文档也没有意义:

DBNull类表示不存在的值.例如,在数据库中,表行中的列可能不包含任何数据.也就是说,该列被认为根本不存在而不仅仅是没有值.DBNull对象表示不存在的列.此外,COM interop使用DBNull类来区分VT_NULL变量(表示不存在的值)和VT_EMPTY变量(表示未指定的值).

什么是关于"不存在的列"的废话?存在一列,它只是没有特定行的值.如果它不存在,我会尝试访问特定的单元格,而不是DBNull!我可以理解区分VT_NULL和之间的必要性VT_EMPTY,但是为什么不做一个COMEmpty类呢?这将是整个.NET框架中更适合的.

我错过了什么吗?任何人都可以解释为什么DBNull被发明以及它有助于解决的问题?

.net history dbnull rationale

69
推荐指数
3
解决办法
1万
查看次数

为什么不是`printf`中定义的`float`的说明符?

它看起来像它可能是,有(至少在C99),可以适用于长度修改int:%hhd,%hd,%ld%lldsigned char,short,longlong long.甚至还有一个长度修饰符适用于double:%Lf均值long double.

问题是他们为什么省略float?按照模式,它可能是%hf.

c floating-point printf rationale c-standard-library

69
推荐指数
4
解决办法
3392
查看次数

C++ 14变量模板:它们的目的是什么?任何用法示例?

C++ 14将允许创建模板化的变量.通常的例子是变量'pi',可以读取它以获得各种类型的数学常数π的值(3表示int;可能的最接近的值float等)

除此之外,我们可以通过将变量包装在模板化的结构或类中来实现此功能,这与类型转换如何混合?我看到一些重叠.

除了pi示例之外,它如何与非const变量一起使用?任何用法示例,以了解如何充分利用此类功能及其目的是什么?

c++ templates rationale c++14

52
推荐指数
5
解决办法
3万
查看次数

'git submodule init'有什么意义?

背景

要填充存储库的子模块,通常会调用:

git submodule init
git submodule update
Run Code Online (Sandbox Code Playgroud)

在这种用法中,git submodule init似乎只做一件事:填充.git/config已经存在的信息.gitmodules.

那是什么意思?

不能git submodule update简单地使用来自的信息.gitmodules?这样可以避免:

  • 一个不必要的命令(git submodule init); 和
  • 不必要的数据重复(.gitmodules内容到.git/config).

或者:

  • 有用例git submodule init我不知道(在这种情况下,请赐教!); 要不然
  • git submodule init 可以在Git中弃用而没有任何伤害.

以下哪一项是正确的?

git rationale git-submodules

44
推荐指数
2
解决办法
3万
查看次数

C++ 11是否会改变显式调用std :: swap的行为以确保找到ADL定位的swap,如boost :: swap?

背景

考虑以下代码:

#include <utility>

namespace ns
{
    struct foo
    {
        foo() : i(0) {}
        int i;

    private:
        foo(const foo&); // not defined,
        foo& operator=(const foo&); // non-copyable
    };

    void swap(foo& lhs, foo& rhs)
    {
        std::swap(lhs.i, rhs.i);
    }
}

template <typename T>
void do_swap(T& lhs, T& rhs); // implementation to be determined

int main()
{
    ns::foo a, b;
    do_swap(a, b);
}
Run Code Online (Sandbox Code Playgroud)

在C++ 03中,这种实现do_swap将被视为"已损坏":

template <typename T>
void do_swap(T& lhs, T& rhs)
{
    std::swap(lhs, rhs);
}
Run Code Online (Sandbox Code Playgroud)

通过明确指定std::,它禁止ns::swap …

c++ swap rationale language-lawyer c++11

29
推荐指数
2
解决办法
3208
查看次数

为什么 C++ 的“使用命名空间”的工作方式如此?

所有学生都对 C++ using-directives的行为感到惊讶。考虑这个片段(Godbolt):

namespace NA {
    int foo(Zoo::Lion);
}
namespace NB {
    int foo(Zoo::Lion);
    namespace NC {
        namespace N1 {
            int foo(Zoo::Cat);
        }
        namespace N2 {
            int test() {
                using namespace N1;
                using namespace NA;
                return foo(Zoo::Lion());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你可能认为test会叫NAfoo(Zoo::Lion); 但实际上它最终会调用N1's foo(Zoo::Cat)

原因是这using namespace NA实际上并没有将名称NA带入当前范围;它带来他们到最小共同祖先的范围NAN2,这是::。并且using namespace N1不会将名称N1带入当前 …

c++ using-directives rationale name-lookup c++98

26
推荐指数
1
解决办法
815
查看次数

为什么拥有多行constexpr功能是不正确的?

根据广义常量表达式 - 修订版5,以下是非法的.

constexpr int g(int n) // error: body not just ‘‘return expr’’
{
    int r = n;
    while (--n > 1) r *= n;
    return r;
}
Run Code Online (Sandbox Code Playgroud)

这是因为所有'constexpr'函数都必须具有这种形式{ return expression; }.我看不出有任何理由需要这样做.

在我看来,唯一真正需要的是不读取/写入外部状态信息,传入的参数也是'constexpr'语句.这意味着对具有相同参数的函数的任何调用都将返回相同的结果,因此可以在编译时"知道".

我的主要问题是,它似乎只是强迫你做一些真正的回旋形式的循环,并希望编译器优化它,以便它对非constexpr调用同样快.

constexpr为上面的例子写一个有效的,你可以这样做:

constexpr int g(int n) // error: body not just ‘‘return expr’’
{
    return (n <= 1) ? n : (n * g(n-1));
}
Run Code Online (Sandbox Code Playgroud)

但是这很难理解,你必须希望编译器在使用违反要求的参数调用时处理尾递归const-expr.

c++ rationale c++11

25
推荐指数
2
解决办法
5988
查看次数

是否有特定原因在C++中不允许嵌套的命名空间声明?

该标准不允许这样的代码:

namespace Hello::World {

//Things that are in namespace Hello::World

}
Run Code Online (Sandbox Code Playgroud)

而是要求

namespace Hello { namespace World {

//Things that are in namespace Hello::World

}}
Run Code Online (Sandbox Code Playgroud)

理由是什么?这当时根本没有想到,还是有一个特定的原因不包括在内?

似乎第一个语法更直接地表达了应该在哪个命名空间中,因为声明模仿了以后代码中命名空间的实际使用.如果你不幸使用"哑"括号计算缩进工具,它也会减少缩进.

c++ namespaces language-design rationale

25
推荐指数
3
解决办法
5596
查看次数

C++:隐藏规则背后的基本原理

C++中隐藏规则背后的基本原理是什么?

class A { void f(int); }
class B : public A { void f(double); } // B::f(int) is hidden
Run Code Online (Sandbox Code Playgroud)
  • 如果它是一个有意义的功能,我认为也应该可以隐藏功能而无需定义具有相同名称的新功能:如下所示:

    class B : public A { hide void f(double); }
    
    Run Code Online (Sandbox Code Playgroud)

    但这是不可能的.

  • 我不认为它简化了编译器的工作,因为编译器必须能够在显式使用指令时取消隐藏函数using:

    class B : public A { using A::f; void f(double); } // B::f(int) NOT hidden
    
    Run Code Online (Sandbox Code Playgroud)

那么,怎么会有隐藏规则呢?


嗯,所有三个答案似乎都很好,并且显示了隐藏规则的不同理由.我不确定我应该接受哪个答案.

c++ language-design hide rationale

25
推荐指数
3
解决办法
2175
查看次数

我们需要什么std :: as_const()?

C++ 11给了我们std::add_const; 使用C++ 17,我们有了一个新的结构 - std::as_const().前者只是const在你提供的类型之前添加了一个.第二个是函数的正确(模板),而不是类型特征,它似乎也是一样 - 除了类型是rvalue-reference时,在这种情况下它不能被使用.

我不太明白提供的动机std::as_const().为什么我们除此之外还需要它std::add_const

c++ const rationale type-traits c++17

19
推荐指数
2
解决办法
1346
查看次数