Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.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++ 确定选择了哪个重载_C++_C++11_Overload Resolution - Fatal编程技术网

C++ 确定选择了哪个重载

C++ 确定选择了哪个重载,c++,c++11,overload-resolution,C++,C++11,Overload Resolution,假设我有一个任意复杂的重载函数: template <class T> void foo(T&& ); template <class T> void foo(T* ); void foo(int ); 我不知道我会在哪里使用这样的东西-我只是好奇这是否可能 我可能与你的想法相去甚远,但我已经花了很多时间在这方面,值得补充一个答案(可能是一个完全错误的答案): #包括 #包括 模板无效foo(T&&); 模板无效foo(T*); void foo(int

假设我有一个任意复杂的重载函数:

template <class T> void foo(T&& );
template <class T> void foo(T* );
void foo(int );

我不知道我会在哪里使用这样的东西-我只是好奇这是否可能

我可能与你的想法相去甚远,但我已经花了很多时间在这方面,值得补充一个答案(可能是一个完全错误的答案):

#包括
#包括
模板无效foo(T&&);
模板无效foo(T*);
void foo(int);
模板
结构选择:选择{};
模板
结构选择{};
结构查找{
模板
静态constexpr
自动(A&&A){
返回哪个(选项{},std::forward(a));
}
私人:
模板
静态constexpr
自动(选择、A&&){
//你想干什么就干什么
//这里您知道调用的函数是什么
//它是模板void foo(T&&)
//我将它的类型返回到static
返回和静态转换(foo);
}
模板
静态constexpr
自动哪个(选项,A*){
//你想干什么就干什么
//这里您知道调用的函数是什么
//它是模板void foo(T*)
//我将它的类型返回到static
返回和静态转换(foo);
}
模板
静态constexpr
汽车
哪个(选择,A)
->std::如果启用,则启用
{
//你想干什么就干什么
//这里您知道调用的函数是什么
//它是void foo(int)
//我将它的类型返回到static
return&foo;
}
};
int main(){
浮动f=0.42;
静态_断言(find::which(0)==&static_cast(foo),“!”;
静态_断言(find::which(“hello”)==&static_cast(foo),“!”;
静态_断言(find::which(f)==&static_cast(foo),“!”;
静态_断言(find::which(.42)=&static_cast(foo),“!”;
}

我会在短时间内删除这个答案,我希望专家们会诅咒我。:-)

巴里,很抱歉我第一次回答中的误解。一开始我对你的问题理解错误“T.C.”是正确的,这是不可能的,除非在某些罕见的情况下,函数根据给定的参数具有不同的结果类型。在这种情况下,您甚至可以获得函数的指针

#include <string>
#include <vector>
#include <iostream>

//template <class T> T foo(T ) { std::cout << "template" << std::endl; return {}; };
std::string foo(std::string) { std::cout << "string" << std::endl; return {}; };
std::vector<int> foo(std::vector<int>) { std::cout << "vector<int>" << std::endl; return {}; };
char foo(char) { std::cout << "char" << std::endl; return {}; };

template<typename T>
struct Temp
{
    using type = T (*) (T);
};

#define GET_OVERLOAD(func,param) static_cast<Temp<decltype(foo(param))>::type>(func);

int main(void)
{
    auto fPtr1 = GET_OVERLOAD(foo, 0);
    fPtr1({});

    auto fPtr2 = GET_OVERLOAD(foo, std::string{"hello"});
    fPtr2({});

    auto fPtr3 = GET_OVERLOAD(foo, std::initializer_list<char>{});
    fPtr3({});

    auto fPtr4 = GET_OVERLOAD(foo, std::vector<int>{});
    fPtr4({});

    auto fPtr5 = GET_OVERLOAD(foo, std::initializer_list<int>{});
    fPtr5({});

    return 0;
}
#包括
#包括
#包括

//模板T foo(T){std::cout注意到类型不足以区分重载。顺便说一句,我认为这是不可能的。这与库基本原理TS的调用类型特征非常相似,后者已知需要编译器魔法来实现。@T.C.啊,是的,这是我认为的。?这是可能的(至少在gcc中),但我再也找不到解决方案了。我记得当时的想法是,提供一些假构造,在编译过程中会失败,并在整个模板上打印错误。@PreferenceBean我永不满足的好奇心是我面临的一个实际的、实际的问题。如果你只是想列举所有重载,你不需要
选择
。你可以让所有重载返回签名实际上,目的是给所有未模板化的函数(如
void foo(int);
)赋予优先级,然后给模板化的函数赋予优先级。这样,您就可以枚举两个专门化加上所有可用的未模板化函数(不仅仅是示例中的
int
)。当然,它可以用更少的代码来完成,而不是你链接的代码。我读了你对另一个答案的评论(如果我在
void foo(char)
中更改它,它将不起作用).正因为如此,我认为目标是获得未模板化的函数(如果有的话),否则是正确的专门化。
选项
只是帮助对它们进行迭代。
可以通过一种
int
/
char
调度来完成。无论如何,我希望能够成功地解释目标是什么作为。目标是根据正常的重载解析机制选择正确的重载。这是目标。如果你只想枚举所有可能的重载,你不需要任何额外的调度,我链接的内容就足够了。但是枚举重载永远不会起作用(例如,如果有人添加了
名称空间N怎么办{struct X{};void foo(X)}
其他地方…)你说我想知道,对于给定的表达式,调用哪个foo()。你希望这些信息是什么形式的?只是想知道,因为我想我完全误解了这个问题。对不起。
#include<type_traits>
#include<utility>

template <class T> void foo(T&&);
template <class T> void foo(T*);
void foo(int);

template<int N>
struct choice: choice<N+1> { };

template<>
struct choice<3> { };

struct find {
    template<typename A>
    static constexpr
    auto which(A &&a) {
        return which(choice<0>{}, std::forward<A>(a));
    }

private:
    template<typename A>
    static constexpr
    auto which(choice<2>, A &&) {
        // do whatever you want
        // here you know what's the invoked function
        // it's template<typename T> void foo(T &&)
        // I'm returning its type to static_assert it
        return &static_cast<void(&)(A&&)>(foo);
    }

    template<typename A>
    static constexpr
    auto which(choice<1>, A *) {
        // do whatever you want
        // here you know what's the invoked function
        // it's template<typename T> void foo(T *)
        // I'm returning its type to static_assert it
        return &static_cast<void(&)(A*)>(foo);
    }

    template<typename A>
    static constexpr
    auto
    which(choice<0>, A a)
    -> std::enable_if_t<not std::is_same<decltype(&static_cast<void(&)(A)>(foo)), decltype(which(choice<1>{}, std::forward<A>(a)))>::value, decltype(&static_cast<void(&)(A)>(foo))>
    {
        // do whatever you want
        // here you know what's the invoked function
        // it's void foo(int)
        // I'm returning its type to static_assert it
        return &foo;
    }
};

int main() {
    float f = .42;
    static_assert(find::which(0) == &static_cast<void(&)(int)>(foo), "!");
    static_assert(find::which("hello") == &static_cast<void(&)(const char *)>(foo), "!");
    static_assert(find::which(f) == &static_cast<void(&)(float&)>(foo), "!");
    static_assert(find::which(.42) == &static_cast<void(&)(double&&)>(foo), "!");
}
#include <string>
#include <vector>
#include <iostream>

//template <class T> T foo(T ) { std::cout << "template" << std::endl; return {}; };
std::string foo(std::string) { std::cout << "string" << std::endl; return {}; };
std::vector<int> foo(std::vector<int>) { std::cout << "vector<int>" << std::endl; return {}; };
char foo(char) { std::cout << "char" << std::endl; return {}; };

template<typename T>
struct Temp
{
    using type = T (*) (T);
};

#define GET_OVERLOAD(func,param) static_cast<Temp<decltype(foo(param))>::type>(func);

int main(void)
{
    auto fPtr1 = GET_OVERLOAD(foo, 0);
    fPtr1({});

    auto fPtr2 = GET_OVERLOAD(foo, std::string{"hello"});
    fPtr2({});

    auto fPtr3 = GET_OVERLOAD(foo, std::initializer_list<char>{});
    fPtr3({});

    auto fPtr4 = GET_OVERLOAD(foo, std::vector<int>{});
    fPtr4({});

    auto fPtr5 = GET_OVERLOAD(foo, std::initializer_list<int>{});
    fPtr5({});

    return 0;
}
char
string
string
vector<int>
vector<int>