在下面的代码中,类模板使用一个参数,但如果模板参数是模板,则函数模板使用两个。这在使用类型推导时没问题,但在使用显式模板实例化时很奇怪。
是否可以将模板模板参数写为一个参数?
这个问题链接到函数重载匹配模板模板
#include <iostream>
template <typename T>
struct C
{
C (T i)
{
std::cout << "simple" << std::endl;
}
};
template <template<typename TT> class FF, typename TT>
struct C <FF<TT> > // (1)
{
C (FF<TT> i)
{
std::cout << "template" << std::endl;
}
};
template <typename T>
void F (T i)
{
std::cout << "simple" << std::endl;
}
// two template arguments FF and TT.
// Anyway to write this so that the argument count is one?
template <template<typename TT> class FF, typename TT>
void F (FF<TT> i)
{
std::cout << "template" << std::endl;
}
template <typename T>
struct R
{
T x;
};
int main()
{
R<int> r;
C<R<int> >{r}; // prints 'template', as expected
F<R<int> >(r); // prints 'simple', probably not what you think
F<R,int >(r); // prints 'template' as expected but
}
编辑:
我得出的结论是这个问题不是一个好问题,因为如果有一个参数语法,重载决议仍然会选择错误的函数。这让我感到惊讶,但这里是证明它的代码(与以前相同的代码,除了一个模板函数重载发生了变化):
EDIt2:在跳过显式模板规范的主要内容中添加了进一步的打印。
EDIT3:下面的代码是废话。正如@DyP 正确指出的那样,我犯了一个错误。我void F(R<R<T>>)
在明确的情况下打电话而不是void F(R<T>)
.
#include <iostream>
template <typename T>
struct R
{
T x;
};
template <typename T>
struct C
{
C (T i)
{
std::cout << "simple" << std::endl;
}
};
template <template<typename TT> class FF, typename TT>
struct C <FF<TT> > // (1)
{
C (FF<TT> i)
{
std::cout << "template" << std::endl;
}
};
template <typename T>
void F (R<T> i)
{
std::cout << "template" << i.x << std::endl;
}
template <typename T>
void F (T i)
{
std::cout << "simple" << std::endl;
}
int main()
{
R<int> r;
C<R<int> >{r}; // prints 'template', as expected
F<R<int> >(r); // prints 'simple', probably not the expected overload
F (r); // prints 'template', now overload resolution works. Strange.
}