SFINAE再次访问 [英] SFINAE revisited

查看:43
本文介绍了SFINAE再次访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

刚刚遇到一个有关SFINAE的有趣问题。给出

以下代码:


#include< iostream>

#include< typeinfo>


模板< typename T>

class P

{

public:

P(T *){std :: cout<< 在P:正常ctor << std :: endl; }

模板< typename U>

P(U *){std :: cout<< 在P:模板ctor(U ="

<< typeid(U).name()<<'')''<< std :: endl; }

};


B级

{

公开:

虚拟~B(){}

};


int

main()

{

D类:公共B {};

P< B p(新D);

返回0;

}


这应该编译,如果是,那该怎么办?程序输出?

我手头有三个不同的编译器:一个没有编译b
,一个输出在P:正常ctor,一个输出 ;在P:

模板ctor(U = ...)",其中...是错误的名字

D.(我自己的感觉是那个它不应该编译。但是我不是很清楚模板参数演绎,以及在SFINAE开始的时候是什么...... b $ b等级。)


-

James Kanze(GABI软件)电子邮件:ja ********* @ gmail.com

Conseils en信息东方物品/

Beratung in objektorientierter Datenverarbeitung

9placeSémard,78210 St.-Cyr-l''coco,France,+ 33(0)1 30 23 00 34

解决方案

7月15日12:22 * pm,James Kanze< james.ka ... @ gmail.comwrote:
<块quote class =post_quotes>
刚刚遇到一个有关SFINAE的有趣问题。 *给出

以下代码:


* * #include< iostream>

* * #include< typeinfo>


* *模板< typename T>

* * class P

* * {

* * public:

* * * * P(T *){std :: cout<< 在P:正常ctor << std :: endl;}

* * * *模板< typename U>

* * * * P(U *){std :: cout<< 在P:模板ctor(U ="

* * * * * * * * * *<< typeid(U).name()<<''')' '<< std :: endl; }

* *};


* * B级

* * {

* *公开:

* * * *虚拟* * * * * * ~B(){}

* *};


* * int

* * main()

* * {

* * * * D类:公共B {};

* * * * P< B p(新D);

* * * *返回0;

* *}


这应编译,以及如果是这样,程序应该输出什么?

我手边有三个不同的编译器:一个未能编译,b $ b $编译,一个输出在P:正常ctor ;和一个输出在P:

模板ctor(U = ...)中,其中......是错误的名称

D. *(我自己的感觉是它不应该编译。*但我不是

所有关于模板参数演绎的清楚,以及在什么

级SFINAE踢进去。)



这与使用函数

而不是构造函数设置相同有什么不同吗?


模板< typename T>

class Foo

{

public:

void goo(T * a){std :: cout<< 在Foo中:正常fn << std :: endl;}

模板< typename U>

void goo(U * a){std :: cout<<" Int Foo:templated fn" ;<< std :: endl;

};


B级{public:virtual~B(){}};

D类:公共B {};


int main()

{

Foo< Bfoo;

foo.goo(新D);

}


我认为最后一行可靠(并且正确)总是选择

模板化函数,但如果用new B替换会选择

正常fn。


我不明白为什么建筑师应该表现得与众不同(我很好奇

如果你的三个编译器在我的例子中表现不同。


Joe Cook


James Kanze写道:


刚刚遇到一个有关SFINAE的有趣问题。给出

以下代码:


#include< iostream>

#include< typeinfo>


模板< typename T>

class P

{

public:

P(T *){std :: cout<<" In P:normal ctor"< < std :: endl;}

模板< typename U>

P(U *){std :: cout<<"在P:模板中ctor(U ="

<< typeid(U).name()<<'')''<< std :: endl;}

};


B级

{

公开:

虚拟~B (){}

};


int

main()

{

D类:公共B {};

P< B p(新D);

返回0;

}


这应该编译,如果是,那该怎么办?程序输出?

我手头有三个不同的编译器:一个没有编译b
,一个输出在P:正常ctor,一个输出 ;在P:

模板ctor(U = ...)",其中...是错误的名字

D.(我自己的感觉是那个它不应该编译。但是我不是很清楚模板参数扣除,以及SFINAE开始的
等级。)



首先提出一个问题:D是故意的是本地课吗?那是'

我认为它不能编译的唯一原因(模N2580 :-))。


-

Gennaro Prota | < https://sourceforge.net/projects/breeze/>

您是否需要C ++方面的专业知识?我有空。


James Kanze写道:


刚刚遇到一个有关SFINAE的有趣问题。给出

以下代码:


#include< iostream>

#include< typeinfo>


模板< typename T>

class P

{

public:

P(T *){std :: cout<< 在P:正常ctor << std :: endl; }

模板< typename U>

P(U *){std :: cout<< 在P:模板ctor(U ="

<< typeid(U).name()<<'')''<< std :: endl; }

};


B级

{

公开:

虚拟~B(){}

};


int

main()

{

D类:公共B {};

P< B p(新D);

返回0;

}


这应该编译,如果是,那该怎么办?程序输出?

我手头有三个不同的编译器:一个没有编译b
,一个输出在P:正常ctor,一个输出 ;在P:

模板ctor(U = ...)",其中...是错误的名字

D.(我自己的感觉是那个它不应该编译。但是我不是很清楚模板参数扣除,以及SFINAE开始的
等级。)



如果类型扣除由于

结果类型(或从中衍生出来的某些其他元素)不是

自然 C ++元素,但没有明确说明

不良形成的原因。 OTOH,标准是一个模糊的WRT使用本地类型

与模板。如果您订阅严格的标准精神,

然后*任何*使用本地类型作为模板的类型参数不允许

(根据[temp] .arg.type] / 2),所以当''U == D''实例化

的构造函数P(U *)是非法的(但不是非自然的)

构造。在这种情况下,SFINAE不适用。如果你订阅了

宽松的标准,那么当你明确指定模板类型参数时,你应该只避免使用本地类型,而不是当你允许
$时b $ b它是从函数调用中推导出来的。在那种情况下,SFINAE也不会给b $ b申请(因为扣除不能失败),并且模板化的

c-tor只是与''U一起使用== D''。根据后者的说法,Comeau按照原来的策略VC ++行事。


V

-

请在通过电子邮件回复时删除资金''A'

我没有回复最热门的回复,请不要问


Just ran into an interesting question concerning SFINAE. Given
the following code:

#include <iostream>
#include <typeinfo>

template< typename T >
class P
{
public:
P( T* ) { std::cout << "In P: normal ctor" << std::endl ; }
template< typename U >
P( U* ) { std::cout << "In P: template ctor (U = "
<< typeid( U ).name() << '')'' << std::endl ; }
} ;

class B
{
public:
virtual ~B() {}
} ;

int
main()
{
class D : public B {} ;
P< B p( new D ) ;
return 0 ;
}

Should this compile, and if so, what should the program output?
I''ve got three different compilers at hand: one fails to
compile, one outputs "In P: normal ctor", and one outputs "In P:
template ctor (U = ...)", where the ... is the mangled name of
D. (My own feeling is that it shouldn''t compile. But I''m not
all that clear about template argument deduction, and at what
level SFINAE kicks in.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l''école, France, +33 (0)1 30 23 00 34

解决方案

On Jul 15, 12:22*pm, James Kanze <james.ka...@gmail.comwrote:

Just ran into an interesting question concerning SFINAE. *Given
the following code:

* * #include <iostream>
* * #include <typeinfo>

* * template< typename T >
* * class P
* * {
* * public:
* * * * P( T* ) { std::cout << "In P: normal ctor" << std::endl ;}
* * * * template< typename U >
* * * * P( U* ) { std::cout << "In P: template ctor (U = "
* * * * * * * * * * << typeid( U ).name() << '')'' << std::endl ; }
* * } ;

* * class B
* * {
* * public:
* * * * virtual * * * * * * ~B() {}
* * } ;

* * int
* * main()
* * {
* * * * class D : public B {} ;
* * * * P< B p( new D ) ;
* * * * return 0 ;
* * }

Should this compile, and if so, what should the program output?
I''ve got three different compilers at hand: one fails to
compile, one outputs "In P: normal ctor", and one outputs "In P:
template ctor (U = ...)", where the ... is the mangled name of
D. *(My own feeling is that it shouldn''t compile. *But I''m not
all that clear about template argument deduction, and at what
level SFINAE kicks in.)


Is this any different than having the same set-up with functions
instead of constructors?

template<typename T>
class Foo
{
public:
void goo(T* a) { std::cout << "In Foo: normal fn" << std::endl ;}
template<typename U>
void goo(U* a) { std::cout <<"Int Foo: templated fn"<<std::endl;
};

class B { public: virtual ~B(){} };
class D : public B{};

int main()
{
Foo<Bfoo;
foo.goo(new D);
}

I would think this last line reliably (and rightfully) always chooses
the templated function, but if replaced by "new B" would pick the
"normal fn".

I don''t see why Constructors should behave differently (I''d bd curious
if your "three compilers" behave differently in my example.

Joe Cook


James Kanze wrote:

Just ran into an interesting question concerning SFINAE. Given
the following code:

#include <iostream>
#include <typeinfo>

template< typename T >
class P
{
public:
P( T* ) { std::cout << "In P: normal ctor" << std::endl ; }
template< typename U >
P( U* ) { std::cout << "In P: template ctor (U = "
<< typeid( U ).name() << '')'' << std::endl ; }
} ;

class B
{
public:
virtual ~B() {}
} ;

int
main()
{
class D : public B {} ;
P< B p( new D ) ;
return 0 ;
}

Should this compile, and if so, what should the program output?
I''ve got three different compilers at hand: one fails to
compile, one outputs "In P: normal ctor", and one outputs "In P:
template ctor (U = ...)", where the ... is the mangled name of
D. (My own feeling is that it shouldn''t compile. But I''m not
all that clear about template argument deduction, and at what
level SFINAE kicks in.)

First a question: was it intentional that D is a local class? That''s
the only reason I see for it not to compile (modulo N2580 :-)).

--
Gennaro Prota | <https://sourceforge.net/projects/breeze/>
Do you need expertise in C++? I''m available.


James Kanze wrote:

Just ran into an interesting question concerning SFINAE. Given
the following code:

#include <iostream>
#include <typeinfo>

template< typename T >
class P
{
public:
P( T* ) { std::cout << "In P: normal ctor" << std::endl ; }
template< typename U >
P( U* ) { std::cout << "In P: template ctor (U = "
<< typeid( U ).name() << '')'' << std::endl ; }
} ;

class B
{
public:
virtual ~B() {}
} ;

int
main()
{
class D : public B {} ;
P< B p( new D ) ;
return 0 ;
}

Should this compile, and if so, what should the program output?
I''ve got three different compilers at hand: one fails to
compile, one outputs "In P: normal ctor", and one outputs "In P:
template ctor (U = ...)", where the ... is the mangled name of
D. (My own feeling is that it shouldn''t compile. But I''m not
all that clear about template argument deduction, and at what
level SFINAE kicks in.)

SFINAE would kick in if the type deduction would fail due to the
resulting type (or some other element derived from that) is not a
"natural" C++ element, but not an explicitly stated cause of
ill-formedness. OTOH, the Standard is a bit vague WRT using local types
with templates. If you subscribe to the strict spirit of the Standard,
then *any* use of local type as a type argument of a template is not
allowed (according to [temp.arg.type]/2), so the constructor P(U*) that
is instantiated when ''U == D'', is an illegal (but not unnatural)
construct. In that case SFINAE does not apply. If you subscribe to the
relaxed Standard, then you shall only avoid using local types when
specifying the template type argument explicitly, but not when you allow
it to be deduced from a function call. In that case SFINAE doesn''t
apply either (since the deduction cannot "fail"), and the templated
c-tor is simply used with ''U == D''. Comeau behaves according to the
former strategy, VC++ - according to the latter.

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


这篇关于SFINAE再次访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆