Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有一种方法可以使用SFINAE来检测是否未声明非模板化的非成员函数?_C++_Templates_C++11_Sfinae_Decltype - Fatal编程技术网

C++ 有没有一种方法可以使用SFINAE来检测是否未声明非模板化的非成员函数?

C++ 有没有一种方法可以使用SFINAE来检测是否未声明非模板化的非成员函数?,c++,templates,c++11,sfinae,decltype,C++,Templates,C++11,Sfinae,Decltype,我试着用SFINAE和decltype来回答。总而言之,海报需要一个函数,该函数的行为取决于编译单元中是否声明了另一个函数(声明时间是早于所述函数还是晚于所述函数) 我尝试了以下方法: auto some_function_2_impl(int) -> decltype(some_function_1(), void()) { cout << "Using some_function_1" << endl; some_function_1(); }

我试着用SFINAE和decltype来回答。总而言之,海报需要一个函数,该函数的行为取决于编译单元中是否声明了另一个函数(声明时间是早于所述函数还是晚于所述函数)

我尝试了以下方法:

auto some_function_2_impl(int) -> decltype(some_function_1(), void()) {
    cout << "Using some_function_1" << endl;
    some_function_1();
}

void some_function_2_impl(long) {
    cout << "Not using some_function_1" << endl;
}

void some_function_2() {
    return some_function_2_impl(0);
}   
这就是全部要点,我想-我不想定义一些函数的重载,因为一些函数不存在

我认为SFINAE可能需要模板才能工作,所以我尝试了以下方法(这可能有助于表明我不完全知道我在这里做什么):


我做错了什么?

立即查找函数,即使在模板类型中也是如此,除非根据模板参数类型存在可能的ADL查找

然后,在中替换类型之后,完成ADL查找。如果失败,则结果是替换失败

由于函数调用不依赖于参数类型,因此此技术将不起作用

我们仍然可以做一些适度有趣的事情:

template<class T, class...Ts>
struct first_two_match : std::false_type{};
template<class T, class...Ts>
struct first_two_match<T,T,Ts...>:std::true_type{}; // for standard compliance: If the only Ts... that match Ts... is nothing, program ill-formed.
struct secret_type_tag {};
template<class...Ts,
  std::enable_if_t<
    (sizeof...(Ts)==0) || first_two_match<secret_tag_type,Ts...>{}
  >* =nullptr
>
secret_type_tag some_function_1(Ts&&...);

template<bool b>
using bool_t=std::integral_constant<bool, b>;
static const auto some_function_defined = bool_t<
  !std::is_same<secret_tag_type, decltype( some_function_1() )>{}
>;
模板
struct first_two_match:std::false_type{};
模板
struct first_two_match:std::true_type{};//对于标准符合性:如果仅。。。那场比赛。。。没什么,程序格式不正确。
结构秘密类型标签{};
模板*=nullptr
>
秘密类型标记某些功能1(Ts&&;
模板
使用bool_t=std::integral_常数;
静态常数自动某些函数定义=bool\t<
!std::是相同的{}
>;
现在
some_function\u defined
std::true_type
iff有
some_function\u 1
的重载,它比我的
some_function\u 1(Ts&&…
更受欢迎。由于
某些_函数_1(Ts&&…
的优先级非常低,因此首选任何“真实”重载(它不是转发引用glomer,并接受0个参数)

在更复杂的情况下,如果存在真正的重载,则生成这样一个从未选择的低优先级重载是很棘手的


这仍然只是检测在创建
some\u function\u defined
的点上是否定义了
some\u function\u 1
。骗子。

SFINAE is Substitution Failure不是一个错误:如果代码中没有前两个术语,就不能利用它。@black:有没有办法将调用不存在的非模板函数变成替换失败?可以使用预处理器符号来区分“已定义”或“已声明”?他们的意思完全不同。@T.C:说得好,我是说
template <int foo>
auto some_function_2_impl(int) -> decltype(some_function_1(), void()) {
    cout << "Using some_function_1" << endl;
    some_function_1();
}

template <int foo>
void some_function_2_impl(long) {
    cout << "Not using some_function_1" << endl;
}
main.cpp:5:60: error: there are no arguments to 'some_function_1' that 
depend on a template parameter, so a declaration of 'some_function_1'
must be available [-fpermissive]
 auto some_function_2_impl(int) -> decltype(some_function_1(), void()) {
template<class T, class...Ts>
struct first_two_match : std::false_type{};
template<class T, class...Ts>
struct first_two_match<T,T,Ts...>:std::true_type{}; // for standard compliance: If the only Ts... that match Ts... is nothing, program ill-formed.
struct secret_type_tag {};
template<class...Ts,
  std::enable_if_t<
    (sizeof...(Ts)==0) || first_two_match<secret_tag_type,Ts...>{}
  >* =nullptr
>
secret_type_tag some_function_1(Ts&&...);

template<bool b>
using bool_t=std::integral_constant<bool, b>;
static const auto some_function_defined = bool_t<
  !std::is_same<secret_tag_type, decltype( some_function_1() )>{}
>;