【发布时间】:2018-08-02 22:33:43
【问题描述】:
我一直在尝试新的(ish)C++14 变量模板功能,并在编译期间遇到了这个奇怪的错误(g++ 6.3.0,但也使用 8.1.0 进行了测试)
templated_variables.cpp:32:19: error: wrong number of template arguments (1, should be at least 1)
const std::string config_data<WantName> = "Name: grep";
还有比这更多的错误,但它们都是同一类。代码如下
#include <type_traits>
#include <string>
#include <iostream>
struct Want {};
struct WantName : Want {};
struct WantDir : Want {};
template<bool... values>
struct all_of : std::true_type {};
template<bool... values>
struct all_of<true, values...> : all_of<values...> {};
template<bool... values>
struct all_of<false, values...> : std::false_type {};
template <
typename Tag, typename ... Tags,
typename =
typename std::enable_if<
all_of<
std::is_base_of<Want, Tag>::value,
std::is_base_of<Want, Tags>::value...
>::value
>::type
>
const std::string config_data = config_data<Tag> + '\n' + config_data<Tags...>;
template <>
const std::string config_data<WantName> = "Name: grep";
template <>
const std::string config_data<WantDir> = "Directory: /usr/bin/";
int main() {
std::cout << config_data<WantDir, WantName> << '\n';
std::cout << config_data<WantDir> << '\n';
std::cout << config_data<WantName> << '\n';
}
这里的问题似乎是 SFINAE 风格的 std::enable_if,因为如果我删除它,这编译没有问题。但奇怪的是,如果我用config_data<Want*, Want>(或其他以Want 为基础的类)删除config_data<Want*> 的每个实例,我们也不会出现编译错误。
我的问题是,我怎样才能避免不得不这样做
(a) 失去阻止此模板的用户传入随机类型作为模板参数的能力,或
(b) 要求在变量模板的每个实例化中使用不必要的基本参数。
我意识到在这个(人为的)示例中,(a)不是一个合理的问题。任何具有未实现其中一种特化的类型的模板实例化都将无法编译。但这在一般情况下肯定会是一个问题,它仍然没有解释为什么用一个有效的第一个参数、一个空的参数包和一个空白的默认参数来实例化模板会导致编译错误。
【问题讨论】:
-
不同的问题,我相信相同的答案。 stackoverflow.com/questions/34940875
-
确保你在 clang 中尝试奇怪的代码 - 它通常有更好的错误消息并且是一个更好的编译器 godbolt.org/g/kdRQqE:
:20:30: error: template parameter pack must be the last模板参数 typename Tag, typename ... Tags, -
所以最后一个模板参数是默认的这一事实并不影响参数包需要持续存在。该死。也许有一些方法可以将 SFINAE 的东西移动到变量模板中?我想这是我必须切换到静态函数的地方。
-
@Tyg13 它如何知道您是否指定了最后一个参数,或者您是否为包提供了附加参数,然后期望将默认参数添加到末尾?如果你说
bool char void是指(bool char) void还是(bool char void) void? (paren 中的位表示 ppack 吃什么)
标签: c++ c++14 variadic-templates sfinae variable-templates