与可变模板的罕见错误? [英] Rare bug with variadic templates?

查看:180
本文介绍了与可变模板的罕见错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在程序中使用了可变参数模板,它出现了意外的错误。我孤立的错误,我震惊了它:

I were using variadic templates in a program and it's come up an unexpected error. I isolated the error and I has shocked it:

#include<cctype> 
#include<iostream> // try to delete this line

class A 
{ 
    public: 
        void constructor() 
        {   } 

        template<typename... Args> 
        void constructor( int (*f)(int), Args... args ) 
        { 
            // process( f ) 
            constructor( args... ); 
        } 

        template<typename... Args> 
        A( Args... args ) 
        { 
            constructor( args... ); 
        } 
}; 

int main() 
{ 
    A a; 
    a.constructor( std::isspace ); // ok

    A b( std::isspace ); // error

    return 0; 
}



如果删除#include iostream行, 。然而,如果你把这一行,编译器抛出一个错误:

If you delete the line "#include iostream", the source is compiled alright. However, if you put this line, the compiler throw an error:

prov.cpp: In function ‘int main()’:
prov.cpp:32:22: error: no matching function for call to ‘A::A(<unresolved overloaded function type>)’
prov.cpp:32:22: note: candidates are:
prov.cpp:18:7: note: A::A(Args ...) [with Args = {}]
prov.cpp:18:7: note:   candidate expects 0 arguments, 1 provided
prov.cpp:4:7: note: constexpr A::A(const A&)
prov.cpp:4:7: note:   no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘const A&’
prov.cpp:4:7: note: constexpr A::A(A&&)
prov.cpp:4:7: note:   no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘A&&’


b $ b

我使用这个g ++版本:g ++(Ubuntu / Linaro 4.7.2-11precise2)4.7.2
,我用这个标志编译: g ++ -Wall -pedantic -std = c ++ 11 prov.cpp -o prov

我不明白为什么编译器抛出这个错误。

I don't understand why compiler throws this error. Is it a possible bug?

推荐答案

问题是< cctype> 定义单个函数 isspace ,但添加< iostream> 会为< locale> 中拉入的isspacepaceisspace =nofollow> isspace < cctype> 中的一个是

The problem is that <cctype> defines a single function isspace, but adding <iostream> adds another overload for isspace that is pulled in from <locale>. The one from <cctype> is

int isspace( int ch );

< locale>

template< class charT >
bool isspace( charT ch, const locale& loc );

同时包含 std :: isspace 变得模糊,因此您的代码失败。这只有当你通过你的真正的ctor(而不是构造函数),因为编译器不能决定什么转发。 OTOH,方法构造函数接受一个参数,它已经告诉编译器如何从两个重载中选择

With both included, the std::isspace becomes ambiguous and hence your code fails. This becomes visible only when you route it through your real ctor (instead of constructor) because then the compiler can't decide what to forward. OTOH, the method constructor takes a parameter which already tells the compiler how to choose from both overloads.

这篇关于与可变模板的罕见错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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