相关疑难解决方法(0)

为什么我们不能在类中声明命名空间?

在类中声明一个类是有效的.(嵌套类)

在类中声明命名空间无效.

问题是:是否有任何好的理由(除了c ++语法/语法问题)禁止在类中声明命名空间?


至于我为什么要这样做,这里有一个例子:

让我们对二叉树容器进行基本的转换

template<typename Data>
class binary_tree
{
 public:
  ... stuff ....     

 private:
  ... iterators class declaration ...

 public:
  typedef left_depth_iterator_impl     left_depth_iterator;
  typedef right_depth_iterator_impl    right_depth_iterator;
  typedef left_breadth_iterator_impl   left_breadth_iterator;
  typedef right_breadth_iterator_impl  right_breadth_iterator;

  ... stuff ....     

 private:
  Data         data;
  binary_tree* left;
  binary_tree* right;
};
Run Code Online (Sandbox Code Playgroud)

现在我注意到我的类中有很多迭代器,所以我想在同一个命名空间中重新组合它们,如下所示:

template<typename Data>
class binary_tree
{
 public:
  ... stuff ....     

 private:
  ... iterators class declaration ...

 public:
  namespace iterator
  {
    typedef left_depth_iterator_impl     left_depth;
    typedef right_depth_iterator_impl    right_depth;
    typedef left_breadth_iterator_impl   left_breadth;
    typedef right_breadth_iterator_impl  right_breadth;
  }

  ... stuff …
Run Code Online (Sandbox Code Playgroud)

c++ namespaces class

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

为什么将短空值转换为int null值以便与null进行比较?

当我比较可空的短值时,编译器首先将它们转换为整数以与null进行比较.例如,考虑这个简单的代码:

short? cTestA;
if (cTestA == null) { ... }
Run Code Online (Sandbox Code Playgroud)

它由编译器转换为:

short? CS$0$0001 = cTestA;
int? CS$0$0002 = CS$0$0001.HasValue ? new int?(CS$0$0001.GetValueOrDefault()) : null;
if (!CS$0$0002.HasValue){ ... }
Run Code Online (Sandbox Code Playgroud)

这适用于包括.NET 4在内的所有.NET版本.

我在这里错过了什么?仅针对HasValue检查进行双重转换的原因是什么?

跟进

我期望编译器做的是使用.HasValue进行简单的检查if (cTestA.HasValue){}.至少这是我在发现此转换后在代码中执行的操作.

为什么所有这些额外的代码都添加了这么简单的测试?

c# compiler-construction nullable

40
推荐指数
2
解决办法
4881
查看次数

C#编译器编号文字

有谁知道C#编译器编号文字修饰符的完整列表?

默认情况下,声明'0'使其成为Int32,'0.0'使其成为'Double'.我可以在末尾使用文字修饰符"f"来确保将某些内容视为"单个".比如这样......

var x = 0;    // x is Int32
var y = 0f;   // y is Single
Run Code Online (Sandbox Code Playgroud)

我可以使用的其他修饰符是什么?是否有一个强制Double,Decimal,UInt32?我试着谷歌搜索但找不到任何东西.也许我的术语是错误的,这就解释了为什么我的空白.任何帮助非常感谢.

c# compiler-construction

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

为什么ushort + ushort等于int?

以前我今天尝试添加两个ushorts,我注意到我必须将结果反馈给ushort.我认为它可能会成为一个uint(以防止可能的意外溢出?),但令我惊讶的是它是一个int(System.Int32).

是否有一些聪明的理由或者是因为i​​nt被视为'基本'整数类型?

例:

ushort a = 1;
ushort b = 2;

ushort c = a + b; // <- "Cannot implicitly convert type 'int' to 'ushort'. An explicit conversion exists (are you missing a cast?)"
uint d = a + b; // <- "Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)"

int e = a + b; // <- Works!
Run Code Online (Sandbox Code Playgroud)

编辑:就像GregS的回答所说,C#规范说两个操作数(在这个例子中是'a'和'b')应该转换为int.我对为什么这是规范的一部分的根本原因感兴趣:为什么C#规范不允许直接对ushort值进行操作?

c# types integer-arithmetic

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

为什么G ++编译器不能以同样的方式处理这两个函数?

我有一个A零和一个数组.我想找到所有数字的总和A.我想测试两个函数:

第一个功能

void test1(int curIndex){
    if(curIndex == size) return;
    test1(curIndex+1);
    s+=A[curIndex];
}
Run Code Online (Sandbox Code Playgroud)

第二功能

void test2(int curIndex){
    if(curIndex == size) return;
    s+=A[curIndex];
    test2(curIndex+1);
}
Run Code Online (Sandbox Code Playgroud)

我使用PAPI库来计算指令数量,这是整个实验:

#include <iostream>
#include <fstream>
#include "Statistics.h"

using namespace std;


int size;
int *A;
int s;

void test3(int curIndex){
    if(curIndex == size) return;
    test3(curIndex+1);
    s+=A[curIndex];
}

int main(int argc, char* argv[]){

    size = atoi(argv[1]);
    if(argc!=2){
        cout<<"type ./executable size{odd integer}"<<endl;
        return 1;
    }
    if(size%2!=1){
        cout<<"size must be an odd number"<<endl;
        return 1; …
Run Code Online (Sandbox Code Playgroud)

c++ performance

28
推荐指数
1
解决办法
1894
查看次数

在 C# 中,为什么“in”参数不能在本地函数中使用?

例如,

public int DoSomething(in SomeType something){
  int local(){
     return something.anInt;
  }
  return local();
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器会发出无法在局部函数中使用 some 变量的错误?

c# ref nested-function c#-7.0 local-functions

15
推荐指数
1
解决办法
1151
查看次数

为什么我不能返回对字典值的引用?

public class PropertyManager
{
    private Dictionary<ElementPropertyKey, string> _values = new Dictionary<ElementPropertyKey, string>();
    private string[] _values2 = new string[1];
    private List<string> _values3 = new List<string>();
    public PropertyManager()
    {
        _values[new ElementPropertyKey(5, 10, "Property1")] = "Value1";
        _values2[0] = "Value2";
        _values3.Add("Value3");
    }

    public ref string GetPropertyValue(ElementPropertyKey key)
    {
        return ref _values[key]; //Does not compile. Error: An expression cannot be used in this context because it may not be returned by reference.         
    }

    public ref string GetPropertyValue2(ElementPropertyKey key)
    {
        return ref _values2[0]; //Compiles
    }

    public …
Run Code Online (Sandbox Code Playgroud)

ref c#-7.0

5
推荐指数
1
解决办法
265
查看次数

并非所有代码路径都返回一个值 - 但它们确实存在

以下代码提取无法编译导致not code paths return a value.这两种类型Test1StandardChargeCalculator,并Test2StandardChargeCalculator从返回类型的.

我知道如何解决这个问题,但我的问题是我为什么要这样做?A bool是值类型 - 因此只能表示truefalse,这两个都在此代码段中得到满足.那么编译失败的原因呢?

internal StandardChargeCalculator Create()
{
      bool value = true;

      switch (value)
      {
          case true:
              return new Test1StandardChargeCalculator();
          case false:
              return new Test2StandardChargeCalculator();
      }
} //not all code paths return a value
Run Code Online (Sandbox Code Playgroud)

.net c# compiler-errors value-type

4
推荐指数
1
解决办法
1169
查看次数

为什么需要数字后缀?

C#语言(以及我确定的其他语言)在数字文字的末尾需要后缀.这些后缀表示文字的类型.例如,5m是小数,5f是浮点数.

我的问题是:这些后缀真的是必要的,还是可以从其上下文推断出文字的类型?

例如,代码decimal d = 5.0应该推断出它5.0不是double,而是小数.这种语法会导致问题吗?

c# compiler-construction

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

C#闭包堆分配在方法开始时发生

我似乎遇到了C#编译器的一些奇怪行为.

请考虑以下代码示例:

static void Main(string[] args)
{
    Foo(false, 8);
}

public static void Foo(bool execute, int x)
{
    if (execute)
    {
        Task.Run(() => Console.WriteLine(x));
    }
}
Run Code Online (Sandbox Code Playgroud)

运行此(在发布中)显示发生了一些意外的分配.检查IL表明闭包触发的堆分配出现在函数的最开头,而不是在条件内:

  .method public hidebysig static void 
    Foo(
      bool execute, 
      int32 x
    ) cil managed 
  {
    .maxstack 2
    .locals init (
      [0] class Test.Program/'<>c__DisplayClass1_0' 'CS$<>8__locals0'
    )

    IL_0000: newobj       instance void Test.Program/'<>c__DisplayClass1_0'::.ctor()
    IL_0005: stloc.0      // 'CS$<>8__locals0'
    IL_0006: ldloc.0      // 'CS$<>8__locals0'
    IL_0007: ldarg.1      // x
    IL_0008: stfld        int32 Test.Program/'<>c__DisplayClass1_0'::x

    // [18 13 - 18 25]
    IL_000d: ldarg.0 …
Run Code Online (Sandbox Code Playgroud)

.net c# closures roslyn

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

为什么C#不让我像字典一样进行动态索引?

dynamicC#中的关键字可以让我这样做:

dynamic obj = ....;
var foo = obj.foo;
Run Code Online (Sandbox Code Playgroud)

obj.foo在运行时解析属性引用的位置.

由于属性是在运行时解析的,为什么不能将属性本身指定为变量?例如,

var propName = "foo";
var foo = obj[propName];
Run Code Online (Sandbox Code Playgroud)

我知道你可以通过反射或将对象转换为Dictionary来完成类似的事情.我对解决方案不感兴趣,因为它解释了为什么C#首先不支持类似Javascript的方括号查找.

c# language-design

2
推荐指数
1
解决办法
104
查看次数

为什么C#不支持Interfaces中的不可变属性?

我刚试图实现一个不可变的接口属性后发现,C#显然不支持我正在寻找的行为.我计划的很简单,对象会订阅一个包含不可变泛型属性的接口,这意味着没有setter的属性.但是,令我惊讶的是,订阅类仍然可以添加setter而不会出现任何错误.事实上,似乎C#接口完全忽略了属性的签名.它所关心的只是属性类型和名称.
例如:

namespace Some.Arbitrary.Framework
{
    public interface IIdentifiable<T>
    {
        /// <summary>
        /// Classes that subscribe to this interface
        /// may still add a 'set;' signature.
        /// </summary>
        T Identifier { get; } // the lack of 'set;' is ignored
    }
}
Run Code Online (Sandbox Code Playgroud)

我在StackOverflow上看到很多帖子说C#不支持这种行为,但我的问题是:为什么C#不支持我所描述的接口中的不可变属性?我打算做什么背后的基本设计缺陷?

c# interface

0
推荐指数
1
解决办法
321
查看次数