【发布时间】:2014-04-29 03:49:30
【问题描述】:
我尝试编写一个模板类和输出操作符,如下所示:
#include <iostream>
namespace N
{
template< typename ...types >
struct X
{
static_assert((sizeof...(types) != 0), "zero length");
X() = default;
X(X const &) = default;
X(X &&) = default;
template< typename ...args >
//explicit // does not matter
X(args &&...) { ; }
int value = 10;
};
template< typename ...types >
std::ostream &
operator << (std::ostream & out, X< types... > const & x)
{
return out << x.value;
}
} // namespace N
int main()
{
using namespace N;
X< float > /*const*/ x; // `const` does not matter
std::cout << x << std::endl;
return 0;
}
但是static_assertion 提出了:
main.cpp:9:5: error: static_assert failed "zero length"
static_assert((sizeof...(types) != 0), "zero length");
^ ~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:32:23: note: in instantiation of template class 'N::X<>' requested here
std::cout << x << std::endl;
^
1 error generated.
如果类模板X 和operator << 重载在全局namespace 中定义,那么一切都是一样的。我发现,评论 using namespace N; 行并将 X< float > 替换为 N::X< float > 可以解决问题。
如何解释这种行为?是什么原因?
编辑:
我找到了解决办法:就是把operator <<重载的模板参数改成如下:
template< typename first, typename ...rest >
std::ostream &
operator << (std::ostream & out, X< first, rest... > const & x)
{
return out << x.value;
}
拆分类的typename ..types 是不必要的。此外,由于代码极度臃肿,这根本不可取。
【问题讨论】:
-
使用
'\n'而不是多余的std::endl也可以修复它。
标签: c++ templates c++11 operator-overloading variadic-templates