如何通过编译时返回T值"如果"?

时间:2015-02-10 07:47:17

标签: c++ templates template-meta-programming

我想做类似的事情:

template<typename T>
T func()
{
    if(T is int)
        return 1;
    if(T is std::string)
       return std::string("hello");//this line will not be able to compile if T is int
}

有谁能告诉我如何解决这个问题? THX很多。

3 个答案:

答案 0 :(得分:4)

使用模板专业化,例如......

template<typename T>
T func();

template<>
int func() { return 1; }

template<>
std::string func() { return "hello"; }

enable_if

template<typename T>
typename std::enable_if<std::is_same<T, int>::value, int>::type func()
{
   return 1;
}

template<typename T>
typename std::enable_if<std::is_same<T, std::string>::value, std::string>::type 
func()
{
   return "hello";
}

如果您不仅需要int / string,而且我们可以构造int / string的类型,您可以使用decltype

template<typename T>
auto func() -> decltype(int{std::declval<T>()})
{
   return 1;
}

template<typename T>
auto func() -> decltype(std::string{std::declval<T>()})
{
   return "hello";
}

clang编译这个很好,但是gcc 4.8不能和内部编译器错误一起编译。

答案 1 :(得分:1)

#include <iostream>
#include <string>
template<class T>
struct CommonTraits {
    static T Return(){
    }
};
template<>
struct CommonTraits<int>{
    static int Return(){
        return 1;
    }
};
template<>
struct CommonTraits<std::string>{
    static std::string Return(){
        return std::string("hello");
    }
};

int main ()
{
    std::cout<<CommonTraits<std::string>::Return()<<std::endl;
    std::cout<<CommonTraits<int>::Return()<<std::endl;
}

答案 2 :(得分:0)

这是我能想到的最好的...它使用C ++ 14。

template<typename T, typename Tupple, size_t... index>
constexpr T construct_type(Tupple&& params, std::index_sequence<index...>)
{
    return T(std::get<index>(std::forward<Tupple>(params))...);
}

template<typename T, typename Tupple>
constexpr T construct(Tupple&& params)
{
    return construct_type<T, Tupple>(std::forward<Tupple>(params), std::make_index_sequence<std::tuple_size<typename std::decay<Tupple>::type>::value>{});
}

template<bool cond, typename T, typename F>
struct cond_if
{
    template<typename FirstArgs, typename SecondArgs>
    constexpr T value(FirstArgs&& first, SecondArgs&& second) {return construct<T>(first);}
};

template<typename T, typename F>
struct cond_if<false, T, F>
{
    template<typename FirstArgs, typename SecondArgs>
    constexpr F value(FirstArgs&& first, SecondArgs&& second) {return construct<F>(second);}
};



template<typename T>
constexpr auto func()
{
    return cond_if<std::is_same<T, int>::value, int, std::string>().value(std::make_tuple(1), std::make_tuple("Hello"));
}

template<typename T>
constexpr auto func2()
{
    return cond_if<std::is_same<T, int>::value, int, const char*>().value(std::make_tuple(1), std::make_tuple("Hello"));
}


int main()
{
    static_assert(func<int>() == 1, "NOT COMPILE TIME -- 1");
    static_assert(func2<char>() == "Hello", "NOT COMPILE TIME -- 2");
    static_assert(func<char>() == "Hello", "NOT COMPILE TIME -- 3");
}

输出:

NOT COMPILE TIME -- 3 - Non-constant condition for static assertion.

由于使用std::string,第三个实例不是编译时间。