允许用户向std
命名空间添加显式特化.但是,有一些模板我明确禁止专业化.
我可以和不可以使用哪些模板?
template<class T>
void fun(T){}
template<>
int fun(int){return 0;}
Run Code Online (Sandbox Code Playgroud)
考虑这个例子,它被所有实现拒绝。但是,我在当前标准中没有发现任何有说服力的条款来指定这种显式专业化声明的格式不正确。如果存在的话,规则是什么?
此外,潜在的相关规则可能是[temp.deduct.decl#2]
如果对于如此考虑的一组函数模板,在考虑部分排序后没有匹配或有多个匹配([temp.func.order]),则推导失败,并且在声明情况下,程序有问题-形成。
我认为“匹配”的含义在这里还不够明确,因为“匹配”没有明确定义任何内容。
举个例子,假设我想在列表上写一个monadic和非monadic地图.我将从monadic开始:
import Control.Monad
import Control.Monad.Identity
mapM' :: (Monad m) => (a -> m b) -> ([a] -> m [b])
mapM' _ [] = return []
mapM' f (x:xs) = liftM2 (:) (f x) (mapM f xs)
Run Code Online (Sandbox Code Playgroud)
现在我想重用代码来编写纯map
(而不是重复代码):
map' :: (a -> b) -> ([a] -> [b])
map' f = runIdentity . mapM' (Identity . f)
Run Code Online (Sandbox Code Playgroud)
什么是必要的,使map'
优化的,如果它被明确地写的map
是?特别是:
是否有必要写
{-# SPECIALIZE mapM' :: (a -> Identity b) -> ([a] -> Identity [b]) #-} …
Run Code Online (Sandbox Code Playgroud)我今天开始了.这里是n00b问题7:
当您尝试重载模板函数时,显式特化和常规函数之间的区别是什么?
使用显式专业化的适当情况是什么?我不太明白:
#include <iostream>
template <typename s> void test(s var1);
template <> void test<int>(int var1);
int main(){
test(1);
test(1.1);
test("hello!!");
return 0;
}
template <typename s> void test(s var1){
std::cout << var1 << std::endl;
}
template <> void test<int>(int var1){
std::cout << "int " << var1 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
反对:
#include <iostream>
template <typename s> void test(s var1);
void test(int var1);
int main(){
test(1);
test(1.1);
test("hello!!");
return 0;
}
template <typename s> void test(s var1){
std::cout << var1 << …
Run Code Online (Sandbox Code Playgroud) 如果这段代码无效,那就太好了.但它在概念上是合理的,而GCC 接受它,尽管Comeau没有:
template< typename > struct t;
template<> struct t< int > {} r; // Bad declarator! Don't pee on the carpet!
Run Code Online (Sandbox Code Playgroud)
(编辑:以上编译,但r
似乎没有被声明到任何范围,所以它基本上被忽略.)
显式特化在模板和类之间填充一种下层区域.一旦定义,显式特化声明的类型就完成了.从编译器的角度来看,它不是模板.如果它是参数化模板,则无法声明对象.考虑§14/ 3:
在模板声明,显式特化或显式实例化中,声明中的init-declarator-list最多应包含一个声明符.当这样的声明用于声明类模板时,不允许声明者.
"用于声明类模板"是什么意思?显然,主模板声明了一个类模板.根据§14.5.5/ 1(FDIS编号),部分专业化也是如此:
类模板名称是simple-template-id的模板声明是simple-template-id中指定的类模板的部分特化.
然而,当谈到显式专业化时,标准就说明了令牌序列之前的声明template<>
.它看起来像一个模板,它命名一个模板名称,但它似乎没有声明一个模板.
真正奇怪的是§14/ 3将声明者的数量限制为"最多一个".函数模板声明,显式特化或实例化必须只有一个声明符.涉及类模板的任何声明必须正好为零...除了显式特化,这似乎是通过裂缝.忠实地,海湾合作委员会拒绝允许
template<> struct t< int > {} r, s; // Offer valid one per specialization.
Run Code Online (Sandbox Code Playgroud)
我倾向于同意海湾合作委员会的解释,尽管可能是胡说八道.不幸的是,它可能会抑制其检测缺失的分号的能力.请允许声明者的数量正好为零!
我有一个模板方法如下: -
template<typename T, int length>
void ProcessArray(T array[length]) { ... }
Run Code Online (Sandbox Code Playgroud)
然后我使用上面的方法编写代码: -
int numbers[10] = { ... };
ProcessArray<int, 10>(numbers);
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么我必须明确指定模板参数.不能自动推断,以便我可以使用如下: -
ProcessArray(numbers); // without all the explicit type specification ceremony
Run Code Online (Sandbox Code Playgroud)
我确信我遗漏了一些基本的东西!备一把锤子!
我想知道为什么下面的代码在gcc中运行得很好
#include <iostream>
using namespace std;
template<typename T>
struct F {
static T const value;
};
template<>
struct F<int> { // Specialization
static int const value;
};
template struct F<int>;
template<typename T>
T const F<T>::value = sizeof(T);
template<>
int const F<int>::value = 42;
int main() {
struct F<int> ma;
cout << ma.value;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在MSVC 2012上我无法编译:
#include <iostream>
using namespace std;
template<typename T>
struct F {
static T const value;
};
template<>
struct F<int> { // Specialization
static …
Run Code Online (Sandbox Code Playgroud) c++ templates language-lawyer explicit-specialization explicit-instantiation
我有一个具有成员模板功能的类:
// writer.h
class Writer {
public:
...
template <typename T, typename V>
void addField(const std::string& name, V v)
{
// write something
}
};
Run Code Online (Sandbox Code Playgroud)
在Writer的源文件中,我添加了明确的特化some_type
:
// writer.cpp
template <>
void Writer::addField<some_type, int>(const std::string& name, int v)
{
// specific some_type writing logic
}
Run Code Online (Sandbox Code Playgroud)
这有效......有时候.即使我确定我有合适的类型:
writer.addField<some_type>("name", static_cast<int>(some_value));
Run Code Online (Sandbox Code Playgroud)
有时会调用显式特化,有时会调用主要特征.是什么赋予了?
我在下面的代码中出错:
template<typename T, bool B = is_fundamental<T>::value>
class class_name;
template<>
class class_name<string, false>{
public:
static string const value;
};
template<>
string const class_name<string, false>::value = "Str";
// error: not an entity that can be explicitly specialized.?in VC++)
Run Code Online (Sandbox Code Playgroud)
我该如何解决?
c++ templates template-specialization visual-c++ explicit-specialization
template <typename>
struct A
{
template <typename>
struct B
{
};
};
template <>
template <>
struct A<int>::B<char>
{
static void foo();
};
void A<int>::B<char>::foo()
{
}
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
vc ++编译错误消息:
错误C2906:'void A <int> :: B <char> :: foo(void)':显式特化需要'template <>'
在这种情况下,符合标准的行为是什么?
c++ templates template-specialization language-lawyer explicit-specialization
c++ ×9
templates ×8
visual-c++ ×2
c++11 ×1
ghc ×1
haskell ×1
optimization ×1
overloading ×1
std ×1