我们相信这个例子在C#编译器中出现了一个错误(如果我们错了,请取笑我).这个错误可能是众所周知的:毕竟,我们的示例是对此博客文章中描述的内容的简单修改.
using System;
namespace GenericConflict
{
class Base<T, S>
{
public virtual int Foo(T t)
{ return 1; }
public virtual int Foo(S s)
{ return 2; }
public int CallFooOfT(T t)
{ return Foo(t); }
public int CallFooOfS(S s)
{ return Foo(s); }
}
class Intermediate<T, S> : Base<T, S>
{
public override int Foo(T t)
{ return 11; }
}
class Conflict : Intermediate<string, string>
{
public override int Foo(string t)
{ return 101; }
} …Run Code Online (Sandbox Code Playgroud) c# compiler-construction generics overriding overload-resolution
在重载解析期间,函数对象是否与常规函数区别对待?如果是这样,怎么样?
我遇到了以下情况:用等效可调用函数对象替换函数改变了代码的含义:
#include <iostream>
namespace N
{
enum E { A, B };
void bar(E mode) { std::cout << "N::bar\n"; }
}
template <typename... Args>
void bar(Args&&... args) { std::cout << "global bar\n"; }
int main()
{
bar(N::A);
}
Run Code Online (Sandbox Code Playgroud)
这里的输出是"N :: bar".到目前为止,非常好:ADL找到N :: bar,N :: bar和全局条都是精确匹配,N :: bar是首选,因为它不是模板.
但是如果我将全局条改变为函数对象,就像这样:
#include <iostream>
namespace N
{
enum E { A, B };
void bar(E mode) { std::cout << "N::bar\n"; }
}
struct S
{
template <typename... Args>
void operator()(Args&&... args) { std::cout …Run Code Online (Sandbox Code Playgroud) 使用.NET 4,我很困惑编译器无法解决下面示例中的第一个方法调用.
using System;
namespace MethodResolutionTest
{
class Program
{
static void Main(string[] args)
{
NonGeneric foo = null;
// ambiguous
foo.Ext1(x => new NonGeneric());
// resolves to first Ext1
foo.Ext1(x => new NonGeneric(), 1);
// resolves to first Ext2
foo.Ext2(x => new NonGeneric());
// resolves to first Ext2
foo.Ext2(x => new NonGeneric(), 1);
// resolves to second Ext2
foo.Ext2(x => "foo");
// resolves to second Ext2
foo.Ext2(x => "foo", 1);
// resolves to first Ext3
foo.Ext3(x => new NonGeneric()); …Run Code Online (Sandbox Code Playgroud) 我正在学习SFINAE,这是我第一次尝试打印"YES"仅适用于那些你可以输出的类型std::ostream(暂时忘掉std::operator<<(std::ostream &, T)......):
template <typename T>
void f(const T &) { std::cout << "NO" << std::endl; }
template <typename T, int SFINAE = sizeof(static_cast<std::ostream &(std::ostream::*)(T)>(
&std::ostream::operator<<))>
void f(const T &) { std::cout << "YES" << std::endl; }
Run Code Online (Sandbox Code Playgroud)
虽然它们似乎可以使用f(std::vector<int>())(产生"NO")但编译器抱怨f(0)的含糊不清:http://ideone.com/VljXFh
prog.cpp:16:5: error: call of overloaded 'f(int)' is ambiguous
f(0);
^
prog.cpp:6:6: note: candidate: void f(const T&) [with T = int]
void f(const T &) { std::cout << "NO" << std::endl; } …Run Code Online (Sandbox Code Playgroud) c++ sfinae overload-resolution template-meta-programming c++11
众所周知,函数模板不能部分专门用于C++.当您在概念上尝试实现此目标时,您可以使用两种可能的解决方案.其中一个是使用带有静态函数的结构,可选地用模板函数包装,如下所示:
template <class T, class U>
struct BarHelper
{
static void BarHelp(T t, const U& u)
{
std::cerr << "bar general\n";
}
};
template <class T>
struct BarHelper<T, double>
{
static void BarHelp(T t, const double& u)
{
std::cerr << "bar specialized\n";
}
};
template <class T, class U>
void bar(T t, const U& u)
{
BarHelper<T, U>::BarHelp(t, u);
};
Run Code Online (Sandbox Code Playgroud)
bar 这里是可选的,你可以直接使用结构的静态成员(尽管你必须明确指定所有参数).
另一种方法是重载函数模板:
template <class T, class U>
void func(T t, const U& u)
{
std::cerr << "func general\n";
} …Run Code Online (Sandbox Code Playgroud) 我正在尝试在microsoft C++编译器14.1(Visual Studio 2017)上编译库,但由于对类方法的模糊调用,我得到一个奇怪的错误.经过一些测试后,我分离了以下代码片段:
#include <iostream>
struct Event
{};
template<typename Derived>
struct State
{
public:
template<typename Fsm>
void onEvent(Fsm& fsm, const Event& event)
{
std::cout << "State::onEvent\n";
}
};
struct DerivedState
: State<DerivedState>
{
public:
using State::onEvent;
template<typename Fsm>
void onEvent(Fsm& fsm, const Event& event)
{
std::cout << "DerivedState::onEvent\n";
}
};
struct Context
{};
int main()
{
DerivedState ds;
Context context;
ds.onEvent(context, Event());
}
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
1> c:\ users\pmas\documents\visual studio
2017\projects\consoleapplication3\consoleapplication3\consoleapplication3.cpp(87): error C2668: 'DerivedState::onEvent': ambiguous call to overloaded function
1>c:\users\pmas\documents\visual studio …Run Code Online (Sandbox Code Playgroud) 我试图通过这里列出的书籍来理解 C++ 中的重载解析。我为了澄清我的概念而写的一个这样的例子,其输出我无法理解,如下所示。
#include <iostream>
struct Name
{
operator int()
{
std::cout<<"Name's int version called"<<std::endl;
return 4;
}
operator float()
{
std::cout<<"Name's float version called"<<std::endl;
return 1.1f;
}
};
int main()
{
double a = Name(); //this works and calls Name's float version. But WHY ISN'T THIS AMBIGIOUS?
long double b = Name(); //this does not work. WHY IS THIS AMBIGIOUS?
bool c = Name(); //this does not work. WHY IS THIS AMBIGIOUS?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如您在这里所看到的,该程序在创建 …
c++ overloading type-conversion overload-resolution implicit-conversion
在阅读了如何使这些std :: function参数明确无误后,我完全糊涂了?到目前为止,我认为我理解函数模板的部分排序是什么,但在阅读了这个问题后,我写了三个例子来检查编译器的行为,并且收到的结果很难让我理解.
template <class T>
void foo(T) {}
template <class T>
void foo(T&) {}
int main()
{
int i;
foo<int>(i); // error: call is ambiguous!
}
Run Code Online (Sandbox Code Playgroud)
问题:这两个功能都是可行的,这是显而易见的,但不是那个T&比专业更专业的功能T?相反,编译器会引发模糊的调用错误.
#include <iostream>
template <class T>
struct X {};
template <>
struct X<int>
{
X() {}
X(X<int&> const&) {} // X<int> is constructible from X<int&>
// note: this is not a copy constructor!
};
template <>
struct X<int&> …Run Code Online (Sandbox Code Playgroud) c++ templates partial-ordering language-lawyer overload-resolution
可以看到在下面的代码中,带有int参数的构造函数被调用。我知道int这很好。但是为什么不short呢?的ASCII值作为'A'65 short可以容纳一个。
在什么条件下int调用带有数据类型参数的构造函数?
#include<iostream>
class RightData
{
int x;
public:
RightData(short data)
{
cout<< "Short" << endl;
}
RightData(int data)
{
cout<< "Int" << endl;
}
RightData(float data)
{
cout<< "Float" << endl;
}
~RightData()
{
cout<< "Final";
}
};
int main()
{
RightData *ptr = new RightData('A');
return 0;
}
Run Code Online (Sandbox Code Playgroud) 在以下代码中,struct A有两个隐式转换运算符到char和int,并且将结构体的实例与整数常量进行比较2:
struct A {
constexpr operator char() { return 1; }
constexpr operator int() { return 2; }
};
static_assert( A{} == 2 );
Run Code Online (Sandbox Code Playgroud)
代码在 GCC 和 MSVC 中顺利通过,但 Clang 抱怨:
<source>:5:20: error: use of overloaded operator '==' is ambiguous (with operand types 'A' and 'int')
static_assert( A{} == 2 );
~~~ ^ ~
<source>:5:20: note: because of ambiguity in conversion of 'A' to 'float'
<source>:2:15: note: candidate function
constexpr operator …Run Code Online (Sandbox Code Playgroud) c++ ×8
c++11 ×4
c# ×2
generics ×2
overloading ×2
templates ×2
.net ×1
constructor ×1
crtp ×1
overriding ×1
sfinae ×1
types ×1