2016-12-15 5 views
0
namespace Random 
{ 
    std::mt19937 engine_{ std::random_device{}() }; 

    template<class T, class = std::enable_if_t<std::is_integral<T>::value>> 
    auto get(T from, T to) 
    { 
     return std::uniform_int_distribution<T>{from, to}(engine_); 
    } 

    template<class T, class = std::enable_if_t<std::is_same<T, float>::value>> 
    auto get(T from, T to) 
    { 
    return std::uniform_real_distribution<T>{from, to}(engine_); 
    } 

} 
int main() 
{ 
    std::cout.sync_with_stdio(false); 
    std::cout.setf(std::ios_base::boolalpha); 
    std::cout << Random::get<float>(1.0f, 2.5f);//COMPILE TIME ERROR 
    std::cin.get(); 
} 

컴파일러 출력 : 18 : 4 : 오류 : 4 : 참고 : '템플릿 T 랜덤 ::의 재정 12'템플릿 T 랜덤 (T, T)를 얻을 :: ' 'int()'함수에서 : 28:44 : 오류 : 'get (float, float)'호출에 일치하는 함수가 없습니다. 28:44 : 참고 : 후보는 다음과 같습니다. : 12 : 4 : 참고 : 템플릿 T 랜덤 (T, T)를 얻을 :: 12 : 4 : 참고 : 템플릿 인수 공제/대체 실패 :C++ 템플릿 함수 오버로드 확인 버그

이 작품 미세 :

#include <type_traits> 
#include <random> 
#include <iostream> 

namespace Random 
{ 
    std::mt19937 engine_{ std::random_device{}() }; 

    template<class T, class = std::enable_if_t<std::is_integral<T>::value>> 
    auto get(T from, T to) 
    { 
     return std::uniform_int_distribution<T>{from, to}(engine_); 
    } 

    template<class T, class = std::enable_if_t<std::is_same<T, float>::value>> 
    T get(T from, T to) 
    { 
    return std::uniform_real_distribution<T>{from, to}(engine_); 
    } 

} 
int main() 
{ 
    std::cout.sync_with_stdio(false); 
    std::cout.setf(std::ios_base::boolalpha); 
    std::cout << Random::get<float>(1.0f, 2.5f);//GOOD 
    std::cin.get(); 
} 

이것은 :

#include <type_traits> 
#include <random> 
#include <iostream> 

namespace Random 
{ 
    std::mt19937 engine_{ std::random_device{}() }; 

    template<class T, class = std::enable_if_t<std::is_integral<T>::value>> 
    auto get(T from, T to) 
    { 
     return std::uniform_int_distribution<T>{from, to}(engine_); 
    } 

    template<class T> 
    std::enable_if_t<std::is_same<T, float>::value, T> 
    get(T from, T to) 
    { 
     return std::uniform_real_distribution<T>{from, to}(engine_); 
    } 

} 
int main() 
{ 
    std::cout.sync_with_stdio(false); 
    std::cout.setf(std::ios_base::boolalpha); 
    std::cout << Random::get<float>(1.0f, 2.5f);//GOOD 
    std::cin.get(); 
} 

왜 컴파일러는 첫 번째 예에서이 해상도를 해결할 수 있습니까?

답변

0

기본 인수는 서명의 일부가 아닌, 그래서 당신은 (추론 된 반환 값의 형태가 다를 것입니다 경우에도) 동일한 서명

로 볼 수

template <typename T, typename> 
auto get(T, T) { /* implementation2 */ } 

template <typename T, typename> 
auto get(T, T) { /* implementation1 */ } 

비교

작업 예제에서 서로 다른 서명이 있습니다 (자동으로 T로 추론하더라도)

template <typename T, typename> 
auto get(T, T) { /* implementation1 */ } 

template<class T, typename> 
T get(T, T) { /* implementation2 */ } 

또는
template <typename T> 
std::enable_if_t<std::is_same<T, float>::value, T> 
get(T, T) { /* implementation2 */ } 

과 통화가 SFINAE에 모호한 감사하지 않습니다.

다른 방법

auto 반환 유형을 허용하고

template<class T, std::enable_if_t<std::is_integral<T>::value>* = nullptr> 
auto get(T from, T to) 
{ 
    return std::uniform_int_distribution<T>{from, to}(engine_); 
} 

template<class T, std::enable_if_t<std::is_same<T, float>::value>* = nullptr> 
auto get(T from, T to) 
{ 
    return std::uniform_real_distribution<T>{from, to}(engine_); 
} 
+0

와우, 이상한 것 SFINAE를 사용합니다. C++은 내가 볼 때 crutchs로 가득합니다 = ((C++에 깊이 들어가면 더 많은 부정을 발견하게됩니다.) THX FOR ANSWER –