简短版本:参数后面的命名参数out给出了编译器错误,但我在语言规范中找不到对此行为的任何支持.
长版:
我正在使用Enum.TryParse<TEnum>三个参数重载,但我更喜欢命名ignoreCase参数以使我的代码更清晰,调用如下:
MyEnum res;
b = Enum.TryParse<MyEnum>(inputString, true, out res);
Run Code Online (Sandbox Code Playgroud)
留下布尔不清楚的含义(除非这个方法已知1).因此我想用:
b = Enum.TryParse<MyEnum>(inputString, out res, ignoreCase: true);
Run Code Online (Sandbox Code Playgroud)
但是,编译器将此报告为错误:
命名参数'ignoreCase'指定已为其指定了位置参数的参数
并且IDE突出显示该ignoreCase参数.针对.NET 4的VS2010以及针对4或4.5的VS11 Beta都会产生相同的结果.在所有情况下,命名out参数都会删除错误.
b = Enum.TryParse<MyEnum>(inputString, result: out res, ignoreCase: true);
Run Code Online (Sandbox Code Playgroud)
我已经在框架和我的程序集中尝试了许多不同的方法(包括避免泛型)2:总是相同的结果:out参数后跟命名参数会产生错误.
我看不出有什么理由错误,并且第7.5.1节参数列表中的C#语言规范:4.0版似乎并没有提供任何理由的out,然后命名参数应该给出一个错误.错误的文本似乎支持解释为一个错误:没有位置参数可能是一个有效的匹配ignoreCase.
我对规范的解读是错误的吗?或者这是编译器错误?
C#7.2更新
当使用C#7.2解除调用时,对所有命名参数的这种限制必须遵循位置参数.
请参阅https://docs.microsoft.com/en-gb/dotnet/csharp/whats-new/csharp-7-2#non-trailing-named-arguments.
1因此,框架设计指南中的建议更倾向于enum参数.
2例如:给定:
private static void TestMethod(int one, float two, out …Run Code Online (Sandbox Code Playgroud) 首先,一点背景(如果不感兴趣,可以跳过一点).我很生气,很困惑!这应该是一个非常简单的用例,事实上我的代码已经用Eclipse JDT编译器编译得很好,所以直到现在我一直在配置Maven以确保这样做.尽管它不能用Oracle JDK和OpenJDK编译,但是我一直在困扰我,因为我认为它可能实际上是我的代码的问题,所以我再次研究它.
我想也许这个bug是在JDT编译器中允许它编译的,而不是Oracle JDK和OpenJDK因为不允许它,我也用它来测试这两个.有问题的原始代码要复杂得多,所以我很难看到问题出在哪里,事实上,我很惊讶地发现在不编译的情况下可以减少这个问题的程度.
Eclipse JDT编译器或Oracle JDK和OpenJDK都有一个非常重要的(imho)错误.
这是相关代码的相当小的表示.(Anything的类型绑定可以被任何接口替换,编译器行为不会改变):
public class Bug<X extends Property<?, ?> & Anything> {
}
interface Property<C, S extends C> extends PropertyConst<C> {
@Override
public S get();
}
interface PropertyConst<C> {
public C get();
}
interface Anything {
}
Run Code Online (Sandbox Code Playgroud)
总而言之,我认为这应该编译得很好,但Oracle JDK 7&8和OpenJDK 7不同意.它使用Eclipse Juno为我编译.
当使用这些编译器中的任何一个编译时,上面的代码给出类似于以下错误的东西,但是对于JDT编译器工作得很好:
Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
^
1 …Run Code Online (Sandbox Code Playgroud) 我有以下C++ 11代码;
template<typename... T>
int g(T... t)
{
return 0;
}
template<class... Args>
void f(Args... args)
{
auto lm = [&, args...] { return g(args...); };
lm();
}
int main()
{
f(2, 5, 7);
}
Run Code Online (Sandbox Code Playgroud)
据我所知,我相信它是有效的C++ 11; 标准第5.1.2.23节;
捕获后跟省略号是包扩展(14.5.3).[例如:
Run Code Online (Sandbox Code Playgroud)template<class... Args> void f(Args... args) { auto lm = [&, args...] { return g(args...); }; lm(); }- 结束例子]
然而,虽然Clang ++编译得很好,但G ++提供了这个错误;
main.cpp: In function 'void f(Args ...)':
main.cpp:10:23: error: expected ',' before '...' token
auto lm = [&, args...] { …Run Code Online (Sandbox Code Playgroud) 你能解释一下STL容器如何使用空的初始化列表处理赋值运算符?
当我做这样的事情:
vector<int> v;
v = { };
Run Code Online (Sandbox Code Playgroud)
被调用的函数不是:
vector& operator= (initializer_list<value_type> il);
Run Code Online (Sandbox Code Playgroud)
但:
vector& operator= (vector&& x);
Run Code Online (Sandbox Code Playgroud)
另一方面,当我和我自己的班级做类似的事情时:
struct A {
A& operator= (const A&) { return *this; }
A& operator= (A&&) { return *this; }
A& operator= (initializer_list<int>) { return *this; }
};
/* ... */
A a;
a = { };
Run Code Online (Sandbox Code Playgroud)
代码不能在VS2013上编译,并说:
error C2593: 'operator =' is ambiguous
Run Code Online (Sandbox Code Playgroud)
如果列表不为空,它工作正常,它只是用初始化列表调用函数.只有当列表为空时才会出现问题,在向量上调用rvalue赋值运算符,在我的类上它会给出错误.
如何在向量和其他容器中处理这种情况?
c++ initializer-list overload-resolution compiler-bug visual-studio-2013
我有一个C++ 11程序,检查一个数字是否为素数.程序等待准备就绪的未来对象.准备就绪后,程序会告诉未来对象的提供者功能是否认为该数字是素数.
// future example
#include <iostream> // std::cout
#include <future> // std::async, std::future
#include <chrono> // std::chrono::milliseconds
const int number = 4; // 444444443
// a non-optimized way of checking for prime numbers:
bool is_prime (int x) {
for (int i=2; i<x; ++i) if (x%i==0) return false;
return true;
}
int main ()
{
// call function asynchronously:
std::future<bool> fut = std::async (is_prime, number);
// do something while waiting for function to set future:
std::cout << "checking, please wait"; …Run Code Online (Sandbox Code Playgroud) 以下代码在Visual C++ 2013中编译,但不在G ++ 4.8.2下编译:
template<class T>
int MyFunc(T& t)
{
return static_cast<int>(CCodes::blah);
}
template<>
int MyFunc(float& t)
{
return 0;
}
int main() {
float f = 10.f;
return MyFunc(f);
}
Run Code Online (Sandbox Code Playgroud)
Visual C++似乎忽略了通用模板函数,因为只MyFunc<float>使用了特化.无论如何,G ++解析了一般函数,并发现尚未定义CCodes枚举.
哪个是对的?或者是这个实现定义的?
使用g ++和编译 -Waggregate-return
#define DOCTEST_CHECK(expr) \
do { \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Waggregate-return\"");\
if(Result failed = (ExpressionDecomposer() << expr)) \
printf("%s\n", failed.m_decomposition.c_str()); \
_Pragma("GCC diagnostic pop"); \
} while(false)
DOCTEST_CHECK(true == false); // produces warnings
Run Code Online (Sandbox Code Playgroud)
但手动展开的版本不会产生任何警告:
do {
_Pragma("GCC diagnostic push");
_Pragma("GCC diagnostic ignored \"-Waggregate-return\"");
if(Result failed = (ExpressionDecomposer() << true == false))
printf("%s\n", failed.m_decomposition.c_str());
_Pragma("GCC diagnostic pop");
} while(false);
Run Code Online (Sandbox Code Playgroud)
这个行为应该不一样吗?
我不认为Result和ExpressionDecomposer类型很重要 - 只是课程.
我正试图让表达式分解像这里一样工作(事情已经重新命名了一下).
编辑: >> here <<是使用lest库的问题的现场演示
我的问题是:为什么?如何使用宏在第一种情况下自由警告?我无法承受全球范围内的警告.
这个问题在之前的g ++中是可重现的-std=c++14.由于const以下代码中突出显示,会生成链接错误.如果const移除RHS,它就会消失.
/* main.cpp */
const char* const arr[2] = {"Hello", "World"};
// ^^^^^
int main () {}
Run Code Online (Sandbox Code Playgroud)
和
/* foo.cpp */
extern const char* const arr[2];
// ^^^^^
const char* foo () { return arr[0]; }
Run Code Online (Sandbox Code Playgroud)
在编译:时g++ [-std=c++11] main.cpp foo.cpp,它会给出以下链接错误:
In function `foo()': undefined reference to `arr'
Run Code Online (Sandbox Code Playgroud)
它是编译器错误还是语言限制/功能?
BadImageFormatException无论使用.NET版本(2.0、3.0、3.5或4),平台或配置如何,在构造的派生类中重写通用迭代器方法都将导致在使用Visual Studio 2010(VS2010)进行编译时引发该错误。在Visual Studio 2012(VS2012)及更高版本中,该问题无法重现。如何避免这种情况?
当步入in中Main在代码MVCE下方(这通常会执行移动到迭代法),BadImageFormatException当该代码在Visual Studio 2010被编译被抛出:
但不在Visual Studio 2012及更高版本中:
public class Program
{
public static void Main(string[] args)
{
foreach ( var item in new ScrappyDoo().GetIEnumerableItems() )
Console.WriteLine(item.ToString());
}
}
public class ScoobyDoo<T>
where T : new()
{
public virtual IEnumerable<T> GetIEnumerableItems()
{
yield return new T();
}
}
public class ScrappyDoo : ScoobyDoo<object>
{
public override IEnumerable<object> GetIEnumerableItems()
{
foreach ( var …Run Code Online (Sandbox Code Playgroud) 考虑以下高度模板化的代码:
// Preamble
#include <list>
#include <deque>
#include <vector>
#include <iostream>
#include <type_traits>
// Rebind template template type traits
template <class> struct rebind_template_template;
template <template <class...> class Template, class... Types>
struct rebind_template_template<Template<Types...>> {
template <class... Args>
using type = Template<Args...>;
};
// Rebind template parameters type traits
template <class> struct rebind_template_parameters;
template <template <class...> class Template, class... Types>
struct rebind_template_parameters<Template<Types...>> {
template <template <class...> class Arg>
using type = Arg<Types...>;
};
// Template pack
template <template <class...> class... Templates>
class …Run Code Online (Sandbox Code Playgroud) c++ template-templates compiler-bug template-argument-deduction c++17
compiler-bug ×10
c++ ×7
c++11 ×3
c# ×2
c++17 ×1
const ×1
eclipse-jdt ×1
future ×1
g++ ×1
generics ×1
java ×1
lambda ×1
openjdk ×1