【问题标题】:Template function specialization default [duplicate]模板函数专业化默认值[重复]
【发布时间】:2017-12-10 08:56:39
【问题描述】:

我正在尝试创建一个适用于特定数据类型的类,并且我希望在不支持数据类型时出现编译时错误。

我试图专门化这样的模板。

template<>
float Foo::get<float>(const std::string& key)
{
    return std::stof(key);
}

并在泛型函数中添加std::static_assert,因为我只需要指定的这些类型。

template<class T>
T Foo::get(const std::string&)
{
    static_assert(false, "unsupported data type");
    return T(0);
}

不幸的是,我得到了编译错误(静态断言失败),即使我有这个类型的专用函数。

我找到了一种仅针对特定类型的方法,但它看起来有点愚蠢而且不是通用的。

T Foo::get(const std::string&)
{
    static_assert(
            std::is_same<T,float>::value ||
            std::is_same<T,double>::value ||
            std::is_same<T,bool>::value ||
            std::is_same<T,uint32_t>::value ||
            std::is_same<T,int32_t>::value ||
            std::is_same<T,std::string>::value,
            "unsuported data type");
    return T(0);
}

【问题讨论】:

  • 为此目的有一个花哨的技巧 (always_false&lt;T&gt;::value),但我认为不定义主模板会更简单。

标签: c++ c++11 templates compiler-errors


【解决方案1】:

您可以根据模板参数T 生成static_assert,然后直到实例化时才会对其进行评估,即确切类型被探索为模板参数的时间。例如

template<class T>
T get(const std::string&)
{
    static_assert(!std::is_same<T, T>::value, "unsupported data type");
    return T(0);
}

LIVE

【讨论】:

  • 我更喜欢static_assert(sizeof(T) == -1, "unsupported data type");,因为它更紧凑。我也相信这是更常见的方法。
  • 我发现并尝试了这个,但它仍然给我这个编译时错误。 .cpp 或标题中的我的专门功能应该在哪里。这还重要吗?
  • @PetarVelev 这确实很重要。至少显式特化的声明必须在使用时可见,否则编译器将从主模板实例化隐式特化(这将给出错误)。
  • @PetarVelev 模板特化不是模板,因此遵循正常的函数定义规则。如果你想把它放在一个标题中,它必须被标记为inline
  • @K.Kirsz:对于static_assert(sizeof(T) == -1,你不能有有效的实例化,所以程序在技术上是错误的。 std::is_same&lt;T, T&gt;::value 可以特化为有效的get
【解决方案2】:

你可以这样做

template <typename> struct AlwaysFalse : false_type {};


template<class T>
T Foo::get(const std::string&)
{
    static_assert(AlwaysFalse<T>::value, "unsupported data type");
}

所以断言是依赖于模板的。

【讨论】:

  • 我很想关闭此副本:stackoverflow.com/questions/30078818/…,这与您的答案相矛盾。有什么想法吗?
  • @bolov:这与我的回答并不矛盾。 AlwaysFalse&lt;T&gt;::value 依赖于 T。我们可能会构造dummy 类并专门化struct AlwaysFalse&lt;dummy&gt; : true_type {}; 以获得Foo::get&lt;T&gt; 的有效实例化。
  • 好吧.. 有这样一句话:“在模板内部,一些构造的语义可能因实例而异。这样的构造取决于模板参数。”
  • @bolov:AlwaysFalse&lt;T&gt;::value 取决于 T,它可能有不同的价值(就像我对 dummy 的专长一样)。相反,false 不能根据T 改变值。
猜你喜欢
  • 2013-12-27
  • 2020-07-25
  • 1970-01-01
  • 2011-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多