关于使用int和static_assert的专业化

Ant*_*nio 5 c++ microcontroller templates static-assert template-specialization

我想编写一个模板函数,只能使用2个数字(例如3和5),如果你尝试将它与其他数字一起使用,则会给出错误.

我可以这样做:

template<int x>
void f();

template<>
void f<3>()
{
   cout << "f<3>()\n";
}


template<>
void f<5>()
{
  cout << "f<5>()\n";
}
Run Code Online (Sandbox Code Playgroud)

然后我可以正常方式调用此函数:

f<3>();
f<5>();
Run Code Online (Sandbox Code Playgroud)

它编译得很好,如果我尝试错误地使用我的函数:

f<10>();
Run Code Online (Sandbox Code Playgroud)

编译器给我一个错误.

我有这个方法的2个问题:

1.-这是标准吗?我可以使用整数专门设计模板吗?

2.-我不喜欢你使用这种方法时得到的错误,因为错误并没有告诉用户他做错了什么.我更喜欢这样写:

template<int x>
void f()
{
    static_assert(false, "You are trying to use f with the wrong numbers");
}
Run Code Online (Sandbox Code Playgroud)

但这不编译.看来我的编译器(gcc 5.4.0)试图首先实例化主模板,因此它给出了(static_assert的)错误.

谢谢您的帮助.

如果您想知道我为什么要这样做是因为我正在学习如何编程微控制器.在微控制器中,你有一些只做一些事情的引脚.例如,引脚3和5是可以生成方波的引脚.如果在一个应用程序中我想生成一个方波,我想写下这样的东西:

square_wave<3>(frecuency);
Run Code Online (Sandbox Code Playgroud)

但是,如果几个月后我想在另一个使用不同微控制器的应用程序中重用这个代码(或更改它),我希望我的编译器对我说:"呃,在这个微控制器中你不能在引脚3中产生方波而5.使用引脚7和9".我认为这可以为我节省很多麻烦(或许不是,我真的不知道.我只是学习如何编程微控制器).

Tri*_*dle 5

1.-这是标准吗?我可以使用整数专门设计模板吗?

是.

2.

template<int x>
void f()
{
    static_assert(false, "You are trying to use f with the wrong numbers");
}
Run Code Online (Sandbox Code Playgroud)

您需要将静态断言条件更改为依赖于模板参数值的内容.简单的事情

template <int x>
void f()
{
    static_assert(x - x, "You are trying to use f with the wrong numbers");
}
Run Code Online (Sandbox Code Playgroud)

应该管用.


顺便说一下,值得注意的是,专门化功能模板通常被认为不是一个好主意,因为专业化与功能重载的交互很糟糕(或者至少有些不可预测).因此,通常使用函数对象可能是一个更好的主意:

template <int I>
struct do_f {
    static_assert(I - I, "You are trying to use f with the wrong numbers");
};

template <>
struct do_f<3> {
    void operator()(args...) { ... }
};

template <>
struct do_f<5> {
    void operator()(args...) { ... }
};
Run Code Online (Sandbox Code Playgroud)

然后你可以编写一个调用函数对象的包装器函数:

template <int I>
void f(args...) {
    do_f<I>{}(args...);
}
Run Code Online (Sandbox Code Playgroud)


son*_*yao 2

的条件static_assert为always false,导致在选择规格之前,在重载决策中无法选择主模板。您可以更改 的条件,static_assert使其取决于模板参数x。。例如

template<int x>
void f()
{
    static_assert(x == 3 || x == 5, "You are trying to use f with the wrong numbers");
}
Run Code Online (Sandbox Code Playgroud)

居住

从标准来看,$17.7/8,9 名称解析 [temp.res]

由于不依赖于模板参数的构造,紧随其定义的模板的假设实例化将是格式错误的

...

否则,对于可以生成有效专业化的模板,不应发出任何诊断信息。

$17.7.2/1 从属名称 [temp.dep]

在模板内部,某些构造的语义可能因实例化而异。这样的构造取决于模板参数。