在C ++ 11(不是更晚)中是否可以编写一个函数来验证在编译时传递给它的字符的唯一性
verify('a');
verify('b');
verify('c');
verify('a'); //should cause compilation error
[由MK编辑回答一些问题]:
答案 0 :(得分:12)
不完全是你要求的,但考虑到你的限制(可以接受相同的范围和宏解决方案),你可以尝试这样的事情:
#define verify(x) class _tmp_##x {};
示例:
int main()
{
verify(a);
verify(b);
verify(a);
return 0;
}
由于重新定义了本地类_tmp_a
,将导致编译失败。
答案 1 :(得分:8)
template<std::size_t X>
struct line_t { enum{value=X}; constexpr line_t(){} };
template<std::size_t line, char c>
constexpr std::integral_constant<bool, false> use_flag(
std::integral_constant<char,c>, line_t<line>
) { return {}; }
#define FLAG_USE( C ) \
constexpr std::integral_constant<bool, true> use_flag( \
std::integral_constant<char,C>, line_t<__LINE__> \
) { return {}; }
template<char c, std::size_t line>
constexpr std::size_t count_uses( line_t<line> from, line_t<1> length ){
return use_flag( std::integral_constant<char, c>{}, from )();
}
template<char c, std::size_t line>
constexpr std::size_t count_uses( line_t<line> from, line_t<0> length ){
return 0;
}
template<char c, std::size_t f, std::size_t l>
constexpr std::size_t count_uses(line_t<f> from, line_t<l> length ){
return count_uses<c>( from, line_t< l/2 >{} )+ count_uses<c>( line_t< f+l/2>{}, line_t<(l+1)/2>{} );
}
#define UNIQUE(C) \
FLAG_USE(C) \
static_assert( count_uses<C>( line_t<0>{}, line_t<__LINE__+1>{} )==1, "too many" )
这应该适用于大小为2 ^ 100s的文件,直到编译器内存不足为止,因为计数是对数深度递归。
类型line_t
启用use_flag
的延迟ADL查找,直到我们调用count_uses
。我们对use_flag
的每个重载进行二叉树求和,文件中每个字符每行一个。