只接受某些参数值的函数(C++)

Tre*_*key 2 c++ templates arguments function c++11

让我设置场景..

您可以在特定模式下打开文件,如下所示:

#include <fstream>

int main(){

    std::fstream myfile;
    myfile.open ("filename", std::ios::app);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

第二个参数是枚举类型 -
这就是为什么你会在尝试这个时遇到编译器错误的原因:

#include <fstream>

int main(){

    std::fstream myfile;
    myfile.open ("filename", std::ios::lksdjflskdjflksff);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这个例子中,类不必考虑第二个参数是不正确的,并且程序员永远不必担心传递无意义的值.

问题: 有没有办法编写必须采用特定类型特定值的函数?

假设我想重新实现类似于上面的文件处理类.区别在于我将第二个参数设为char而不是枚举类型.
我怎么能得到这样的东西:

#include "MyFileHandler.h"

int main(){

    MyFileHandler myfile1;

    myfile.open ("filename", 'a'); //GOOD: a stands for append
    myfile.open ("filename", 't'); //GOOD: t stands for truncate
    myfile.open ("filename", 'x'); //COMPILER ERROR: openmode can not be the value 'x'

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

除此之外,我是否可以让编译器通过功能手段测试参数值的有效性?例:

void IOnlyAcceptPrimeNumbers(const int & primeNumber);
int function(void);

int main(){

    IOnlyAcceptPrimeNumbers(3);       //GOOD: 3 is prime
    IOnlyAcceptPrimeNumbers(7);       //GOOD: 7 is prime
    IOnlyAcceptPrimeNumbers(10);      //COMPILER ERROR: 10 is not prime
    IOnlyAcceptPrimeNumbers(10+1);    //GOOD: 11 is prime
    IOnlyAcceptPrimeNumbers(1+1+1+1); //COMPILER ERROR: 4 is not prime
    IOnlyAcceptPrimeNumbers(function()); //GOOD: can this somehow be done?


    return 0;
}
void IOnlyAcceptPrimeNumbers(const int & primeNumber){return;}
int function(void){return 7;}
Run Code Online (Sandbox Code Playgroud)

我相信我已经说清楚我想做什么以及为什么我觉得这很重要.
有解决方案吗?

Ker*_* SB 6

如果您想要编译时选中的值,则可以编写模板而不是函数参数:

template <char> void foo(std::string const &);      // no implementation

template <> void foo<'a'>(std::string const & s) { /* ... */ } 
template <> void foo<'b'>(std::string const & s) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

用法:

foo<'a'>("hello world");   // OK
foo<'z'>("dlrow olleh");   // Linker error, `foo<'z'>` not defined.
Run Code Online (Sandbox Code Playgroud)

如果您想要一个实际的编译器错误而不仅仅是一个链接器错误,您可以static_assert(false)在主模板中添加一个.