【发布时间】:2019-05-05 20:16:27
【问题描述】:
我有MyClass,这是一个模板类。我想提供一个初始化 r 列表构造函数,以便我可以方便地编写:
MyClass<int> Arr0{ 1, 2, 3, 4, 5, 8 };
另一方面,我不想在这个列表中有重复项,因为这个类意味着只有唯一的用户输入。我见过很多方法来检查数组中的重复项,我想出了has_duplicates() 以下函数。
我尝试结合检查std::initializer_list<T>ed 临时元素(或数组)是否包含成员初始化列表本身中的任何重复元素; 如果它包含static_assert(),则模板实例化,因此不会构造此类的任何对象。
以下是我的代码的最小示例。
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include <iterator>
#include <initializer_list>
template <typename Iterator> // function to check duplicates(which works fine)
constexpr bool has_duplicates(Iterator start, Iterator end)
{
if (start == end) return false;
using Type = typename std::remove_reference_t<decltype(*end)>;
std::map<Type, std::size_t> countMap;
for (; start != end; ++start)
{
countMap[*start]++;
if (countMap[*start] >= 2) return true;
}
return false;
}
template <typename T> class MyClass
{
private:
std::vector<T> m_vec;
public:
MyClass(std::initializer_list<T> a)
: (has_duplicates(a.begin(), a.end()) //-----> here is the problem
? static_assert(false, " the array has duplicates....")
: m_vec(a)
)
{
std::cout << "Constriction successful....";
}
};
int main()
{
std::vector<int> test{ 1, 2, 3, 4, 1 };
std::cout << std::boolalpha
<< has_duplicates(test.begin(), test.end()) << std::endl; // works
MyClass<int> Arr0{ 1, 2, 3, 4 }; // error
return 0;
}
在 MSVC 16.0(C++17 标志)中编译时,这给了我错误:
error C2059: syntax error: 'static_assert'
note: while compiling class template member function 'MyClass<int>::MyClass(std::initializer_list<_Ty>)'
with
[
_Ty=int
]
note: see reference to function template instantiation 'MyClass<int>::MyClass(std::initializer_list<_Ty>)' being compiled
with
[
_Ty=int
]
note: see reference to class template instantiation 'MyClass<int>' being compiled
error C2143: syntax error: missing ';' before '}'
error C2059: syntax error: ')'
error C2447: '{': missing function header (old-style formal list?)
它说一个简单的语法错误,但我没有看到任何 static_assert.
谁能帮我找出错误?
在上述情况下,防止构造 std::initializer_list<T> constutor 参数的正确方法是什么?
【问题讨论】:
-
我认为这是不可能的,因为
std::initializer_list<T>的值只能在运行时确定。 -
std::map不是constexpr类;所以你的has_duplicates()不能初始化constexpr值 -
@cpplearner:给定多个翻译单元,甚至不可能静态地知道每个可能的
initializer_list参数的长度。 -
@cpplearner:我的意思是你甚至不知道可能提供的 set 长度。
标签: c++ c++17 template-meta-programming static-assert stdinitializerlist