今天我的问题很简单:为什么编译器不能从类构造函数中推断模板参数,就像它可以从函数参数那样做?例如,为什么以下代码无效:
template<typename obj>
class Variable {
obj data;
public: Variable(obj d)
{
data = d;
}
};
int main()
{
int num = 2;
Variable var(num); //would be equivalent to Variable<int> var(num),
return 0; //but actually a compile error
}
Run Code Online (Sandbox Code Playgroud)
正如我所说,我明白这是无效的,所以我的问题是为什么不是呢?允许这会产生任何重大的句法漏洞吗?是否存在不希望使用此功能的实例(推断类型会导致问题)?我只是想了解允许函数的模板推理背后的逻辑,但不适用于适当构造的类.
(序言:我是C++ 0x游戏的后续追随者,最近有关从C++ 0x标准中删除概念的争议促使我更多地了解它们.虽然我明白我的所有问题都是完全的假设 - 只要概念在未来一段时间内不是有效的C++代码,如果有的话 - 我仍然有兴趣更多地了解概念,特别是考虑到它将如何帮助我更充分地理解最近的决定背后的优点和随之而来的争议)
在阅读了一些关于概念的介绍性材料之后,就像C++ 0x(直到最近)提出它们一样,我在思考一些语法问题时遇到了麻烦.不用多说,这是我的问题:
1)支持特定派生概念的类型(隐式地,通过auto关键字,还是显式地通过concept_maps)是否也需要独立支持基本概念?换句话说,从另一个(例如concept B<typename T> : A<T>)派生概念的行为是否隐含地包含'隐形'需求声明(在B中requires A<T>;)?混淆源于维基百科关于概念的页面,其中指出:
与类继承一样,满足派生概念要求的类型也满足基本概念的要求.
这似乎说一种类型只需要满足派生概念的要求,而不一定是基本概念的要求,这对我来说没有意义.我知道维基百科远非一个明确的来源; 以上描述只是一个不好的选择?
2)列出类型名称的概念可以是"自动"吗?如果是这样,编译器将如何自动映射这些类型名称?如果没有,是否有任何其他场合在概念上使用'auto'无效?
为澄清,请考虑以下假设代码:
template<typename Type>
class Dummy {};
class Dummy2 { public: typedef int Type; };
auto concept SomeType<typename T>
{
typename Type;
}
template<typename T> requires SomeType<T>
void function(T t)
{}
int main()
{
function(Dummy<int>()); //would this match SomeType?
function(Dummy2()); //how about this?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这些类中的任何一个都会匹配SomeType吗?或者是涉及类型名称的概念所必需的concept_map?
3)最后,我很难理解允许定义哪些公理.例如,我是否可以定义一个逻辑上不一致的公理,例如
concept SomeConcept<typename T>
{
T operator*(T&, int);
axiom …Run Code Online (Sandbox Code Playgroud) 我最近试图测量我的运算符重载/模板能力,并作为一个小测试,创建下面的Container类.虽然此代码编译良好并且在MSVC 2008(显示11)下正常工作,但MinGW/GCC和Comeau都会在operator+重载时阻塞.因为我比MSVC更信任他们,所以我想弄清楚我做错了什么.
这是代码:
#include <iostream>
using namespace std;
template <typename T>
class Container
{
friend Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs);
public: void setobj(T ob);
T getobj();
private: T obj;
};
template <typename T>
void Container<T>::setobj(T ob)
{
obj = ob;
}
template <typename T>
T Container<T>::getobj()
{
return obj;
}
template <typename T>
Container<T> operator+ <> (Container<T>& lhs, Container<T>& rhs)
{
Container<T> temp;
temp.obj = lhs.obj + rhs.obj;
return temp;
}
int main()
{
Container<int> a, …Run Code Online (Sandbox Code Playgroud) 我读litb提问关于SFINAE 在这里,我想知道到底是什么他的代码声明.下面是一个更简单的(没有模板)示例:
int (&a())[2];
Run Code Online (Sandbox Code Playgroud)
究竟是什么声明?&的作用是什么?为了增加我的困惑,如果我宣布以下内容
int b()[2];
Run Code Online (Sandbox Code Playgroud)
我收到一个关于声明一个返回数组的函数的错误,而第一行没有这样的错误(因此,人们会认为第一个声明不是函数).但是,如果我尝试分配一个
a = a;
Run Code Online (Sandbox Code Playgroud)
我得到一个错误,说我正在尝试分配函数...所以现在它是一个函数.究竟是什么东西?