C++ 变量模板在当前编译器中是否正常工作?

C++ 变量模板在当前编译器中是否正常工作?,c++,c++11,g++,visual-studio-2013,mingw,C++,C++11,G++,Visual Studio 2013,Mingw,我尝试根据c++11可变模板功能实现一个简单的元组,如下所示: template <class Head, class... Tail> class tuple; template <class Head> class tuple<Head> { public: tuple(Head h) : m_h( h ) {} tuple(tuple const & rhs) : m_h( rhs.m_h ) {} temp

我尝试根据c++11可变模板功能实现一个简单的元组,如下所示:

template <class Head, class... Tail>
class tuple;

template <class Head>
class tuple<Head>
{
public:
    tuple(Head h) : m_h( h ) {}

    tuple(tuple const & rhs)
    : m_h( rhs.m_h ) {}

    template<class T>
    tuple(tuple<T> const & rhs)
    : m_h( rhs.head() )
    {}

    Head head() const
    {
        return m_h;
    }
private:
    Head m_h;
};

template <class Head, class... Tail>
class tuple : private tuple<Tail...>
{
public:
    typedef tuple<Tail...> inherited;
    tuple(Head h, Tail... tail)
    : inherited(tail...), m_h( h )
    {}

    Head head() const
    {
        return m_h;
    }

    inherited &
    tail()
    {
        return *this;
    }

    inherited const &
    tail() const
    {
        return *this;
    }

    template<typename... Values>
    tuple(tuple<Values...> const & rhs)
    : inherited( rhs.tail() ),
      m_h( rhs.head() )
167:    {}
private:
    Head m_h;
};
模板
类元组;
模板
类元组
{
公众:
元组(头h):m_h(h){}
元组(元组常量和rhs)
:m_h(rhs.m_h){}
模板
元组(元组常量和rhs)
:m_h(右侧头部())
{}
警察局长
{
返回m_h;
}
私人:
头部m_h;
};
模板
类元组:私有元组
{
公众:
typedef元组继承;
元组(头h,尾…尾)
:继承的(尾部…),m_h(h)
{}
警察局长
{
返回m_h;
}
继承的&
尾
{
归还*这个;
}
继承常数&
尾常数
{
归还*这个;
}
模板
元组(元组常量和rhs)
:继承(rhs.tail()),
m_h(右侧头部())
167:    {}
私人:
头部m_h;
};
并尝试按如下方式使用它:

    tuple<int, double, char> tpl(0, 3.3, 'a');
175:    tuple<long, float, short> tpl2 = tpl;
tuple-tpl(0,3.3,'a');
175:元组tpl2=tpl;
这导致:

test.cpp(167) : error C2664: 'tuple<short,>::tuple(const tuple<short,> &)' : can not convert argument 1 from 'const tuple<char,>' to 'short'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
test.cpp(167) : see reference to function template instantiation 'tuple<float,short>::tuple<double,char>(const tuple<double,char> &)' being compiled
test.cpp(167) : see reference to function template instantiation 'tuple<float,short>::tuple<double,char>(const tuple<double,char> &)' being compiled
test.cpp(175) : see reference to function template instantiation 'tuple<long,float,short>::tuple<int,double,char>(const tuple<int,double,char> &)' being compiled
test.cpp(175) : see reference to function template instantiation 'tuple<long,float,short>::tuple<int,double,char>(const tuple<int,double,char> &)' being compiled
test.cpp(167):错误C2664:'tuple::tuple(const tuple&'):无法将参数1从'const tuple'转换为'short'
没有可执行此转换的用户定义的转换运算符,或者无法调用该运算符
cpp(167):请参阅正在编译的函数模板实例化“tuple::tuple(consttuple&)”的引用
cpp(167):请参阅正在编译的函数模板实例化“tuple::tuple(consttuple&)”的引用
cpp(175):请参阅对正在编译的函数模板实例化“tuple::tuple(consttuple&)”的引用
cpp(175):请参阅对正在编译的函数模板实例化“tuple::tuple(consttuple&)”的引用
使用Visual Studio 2013并在中:

c:\Users\achernyaev\Documents\test.cpp: In function 'int main()':
c:\Users\achernyaev\Documents\test.cpp:175:35: error: conversion from 'tuple<int,double, char>' to non-scalar type 'tuple<long int, float, short int>' requested tuple<long,float,short> tpl2 = tpl;
                              ^
c:\Users\achernyaev\Documents\test.cpp:在函数“int main()”中:
c:\Users\achernyaev\Documents\test.cpp:175:35:错误:从“tuple”转换为非标量类型“tuple”请求的tuple tpl2=tpl;
^
使用MinGW的g++4.8.1

问题:这段代码是否真的格式不正确,或者这项功能的支持还不够好


向您致意,Alexander。

代码中有几个错误:下面是一个已更正的错误:

template <class ...> class tuple; // declaration as a multivariate template.

template <class Head>
class tuple<Head>
{
private:
    Head m_h; 
public:
    tuple(Head h) : m_h( h ) {}

    tuple(tuple const & rhs)
    : m_h( rhs.m_h ) {}

    template<class T>
    tuple(tuple<T> const & rhs)
    : m_h( rhs.head() )
    {}

    Head head() const
    {
        return m_h;
    }
};

template <class Head, class... Tail>
class tuple<Head, Tail...> : // explicitly write the partial specialization. 
   private tuple<Tail...> 
{
private:
    Head m_h;

    typedef tuple<Tail...> inherited;
    tuple(Head h, Tail... tail)
    : inherited(tail...), m_h( h )
    {}

    Head head() const
    {
        return m_h;
    }

    inherited &
    tail()
    {
        return *this;
    }

    inherited const &
    tail() const
    {
        return *this;
    }

    template<typename... Values>
    tuple(tuple<Values...> const & rhs)
    : inherited( rhs.tail() ),
      m_h( rhs.head() )    {}
};
模板类元组;//声明为多变量模板。
模板
类元组
{
私人:
头部m_h;
公众:
元组(头h):m_h(h){}
元组(元组常量和rhs)
:m_h(rhs.m_h){}
模板
元组(元组常量和rhs)
:m_h(右侧头部())
{}
警察局长
{
返回m_h;
}
};
模板
类tuple://显式编写部分专门化。
私有元组
{
私人:
头部m_h;
typedef元组继承;
元组(头h,尾…尾)
:继承的(尾部…),m_h(h)
{}
警察局长
{
返回m_h;
}
继承的&
尾
{
归还*这个;
}
继承常数&
尾常数
{
归还*这个;
}
模板
元组(元组常量和rhs)
:继承(rhs.tail()),
m_h(rhs.head()){}
};

转换构造函数的扣减失败:

template<typename... Values>
tuple(tuple<Values...> const & rhs)
: inherited( rhs.tail() ),
  m_h( rhs.head() )
{}

请改进你的标题。题目的答案显然是肯定的。问题:课程的顺序。。切换这两个类。。把有可变模板的放在没有可变模板的前面。这将解决专门化问题。。如图所示:很抱歉让您感到困惑。我纠正的是错误的标记-在更专业的标记之前有一个正向声明,在开始时,我在可变版本之后实现了更专业的标记,但结果是一样的。一个较短的程序似乎也有同样的问题:我不明白为什么它的格式不好。@aschepler:看看error clang gives O.O
忽略候选模板:替换失败[值=]:类模板“tuple”的模板参数太少
在使用它之前不需要声明
m_h
。。OP唯一的问题是在基函数之前声明专门化。。基是可变模板类。这与问题本身无关。变量前向声明出现在专门化之前。是的,您发布的代码正是我试图使用的原始版本,是的,它编译得很好。但问题在于
元组tpl2=tpl必须启用模板ctor时的语句。Yep。对不起,伙计@hivert。你的代码编译得很好。我只是错过了你特化元组的事实。
template<typename H, typename... T>
tuple(tuple<H, T...> const & rhs)
: inherited( rhs.tail() ),
  m_h( rhs.head() )
{}
template <class...> class tuple {};

template <class Head, class... Tail>
class tuple<Head, Tail...> : private tuple<Tail...>
{
public:
    typedef tuple<Tail...> inherited;
    
    tuple(Head h, Tail... tail)
    : inherited(tail...), m_h( h )
    {}

    Head head() const
    {
        return m_h;
    }

    inherited &
    tail()
    {
        return *this;
    }

    inherited const &
    tail() const
    {
        return *this;
    }

    template<typename... T>
    tuple(tuple<T...> const & rhs)
    : inherited( rhs.tail() ),
      m_h( rhs.head() )
    {}

private:
    Head m_h;
};